Spring DI的奇怪行为

时间:2014-03-07 15:09:42

标签: java validation spring-mvc dependency-injection inversion-of-control

我在一个类中注入依赖项。但是当我称之为该类的方法时却找不到。

public StudentValidator extends MyValidator implements Validator{

    private StudentRepository studentRepository;
//setter for the same

 public void validate(Object obj,Errors errors){

    validateStudent(Obj) 
 }
}



public class MyValidator{

  private StudentRepository studentRep;

  public void setStudentRep(StudentRepository studentRep){

     System.out.println("This is printing on Tomcat console");
     this.studentRep=studentRep
     System.out.println("This is also printing"+studentRep+" with hashcode");
  }

  public void validateStudent(Object obj){

     studentRep.findStud();  getting here NullPointerException
  }

 }

不需要编写Spring servlet,因为我可以看到通过Syso语句在setter中注入了依赖项。

同样会出现什么问题?

更新

弹簧servlet.xml中

   <beans>
        <bean id="studentValidator" class="SyudentValidator" >
             <property name="studentRepository" ref="studentRepository">
        </bean>

        <bean id="myValidator" class="MyValidator">
             <property name="studentRep" ref="studentRepository">
        </bean>

         <bean id="studentRepository" class="StudentRepository">


   </beans>

NullPointerException不是我的问题。问题是我在这种情况下获取空指针的原因,因为Syso语句正在打印我的依赖哈希码。

2 个答案:

答案 0 :(得分:0)

假设MyValidator和StudentValidator都是spring bean,你应该尝试:

bean id =“myValidator”class =“MyValidator.java”&gt;

bean id =“studentValidator”class =“StudentValidator.java”parent =“myValidator&gt;

您必须通知spring存在继承。

答案 1 :(得分:0)

您已经两次声明了StudentRepository类型的字段,这令人困惑,但这就是我的想法。

我假设您正在创建StudentValidator的实例,该实例将设置字段StudentValidator.studentRepository。不过,您的validateStudent方法会使用保留MyValidator.studentRep的字段null,因此NullPointerException

基本上,只有方法可以在Java中重写,而不是字段。

如果您确实需要这种不必要的继承结构,则代码应为:

public class MyValidator
{
  private StudentRepository studentRepository;

  public void setStudentRepository(StudentRepository studentRepository)
  {
    this.studentRepository = studentRepository;
  }

  public void validateStudent(Object obj)
  {
    studentRepository.findStud();
  }
}

public StudentValidator extends MyValidator implements Validator
{
  @Override
  public void validate(Object obj, Errors errors)
  {
    validateStudent(Obj) 
  }
}

虽然我很想将其简化为:

public class StudentValidator implements Validator
{
  private StudentRepository studentRepository;

  public void setStudentRepository(StudentRepository studentRepository)
  {
    this.studentRepository = studentRepository;
  }

  @Override
  public void validate(Object obj)
  {
    studentRepository.findStud();
  }
}

<强>更新

根据上面的Spring配置,我可以看到你正在创建这两个类的实例 - 如果你不打算使用myValidator bean作为一个类,那么不确定为什么要这样做? studentValidator bean的父级,但不管怎样,如果你只有一个bean,那么使用父级只会使Spring配置无缘无故。

您在NullPointerException中获得validateStudent的原因是因为您从未在studentRep bean上设置studentValidator,因此您只需将其设置为myValidator <beans> <bean id="studentValidator" class="SyudentValidator" > <property name="studentRepository" ref="studentRepository"> <property name="studentRep" ref="studentRepository"> </bean> <bean id="studentRepository" class="StudentRepository"> bean(他们是两个不同的实例)。

鉴于此,你的Spring配置应该是:

studentRepository

虽然正如我所说,你的类设计首先令人困惑,这使得这个Spring配置看起来很奇怪,因为你正在设置对同一个bean {{1}}的引用,两次。

我的建议是应用我最初建议的类更改,这只是整个设计的设置,并且使得应用程序更难配置为当前正在发生的。