2016-03-07 161 views
3

我正在尝试将对象注入到类中。但是,该字段始终为空。我试过@Autowired@Resource注释。我不在任何地方用new操作符创建对象。正确调用Foo的构造函数。Spring bean被创建,但在Autowired时为null

这个问题的小例子:

Foo类

package foo.bar; 
public class Foo { 
    Foo(){ 
     System.out.println("Foo constructor"); 
    } 
    public void func() { 
     System.out.println("func()"); 
    } 
} 

酒吧类

package foo.bar; 
public class Bar { 
    @Autowired 
    private Foo foo; 

    public Bar() { 
     foo.func(); 
    } 
} 

切入点

package foo.bar; 
public class HelloApp { 
    public static void main(String[] args) { 
     ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); 
    } 
} 

春天-config.xml中

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 
    <context:component-scan base-package="foo.bar"/> 
    <bean id = "foo" class="foo.bar.Foo" /> 
    <bean id = "bar" class="foo.bar.Bar" /> 
</beans> 

为什么现场的fooBar类总是null?我怎样才能解决这个问题?

+3

构造函数被调用。因此调用foo.func();在Bar的构造函数中会产生一个NullPointer。你可以创建一个方法来调用foo.func();并用@PostConstruct对其进行注释以解决此问题 – Mick

回答

2

正如@Mick指出的那样,字段注入必须在构造函数完成后发生(Spring没有其他方式来查看实例并对其进行操作)。修改类使用构造函数注入,你会既让你的依赖更加明确(因此更容易测试,例如)和消除什么本质上是一个竞争条件:

字段是自动装配之前
public class Bar { 
    private Foo foo; 

    @Autowired 
    public Bar(Foo foo) { 
     this.foo = foo; 
     foo.func(); 
    } 
} 
+0

谢谢,这工作得很好。我只是认为在声明bean时,Spring中的整个初始化是(或应该)总是在xml文件中执行。现在我将不得不在某处创建Foo对象并将其传递给构造函数。 – RK1

+0

@ RK1 Spring知道如何自动编写构造函数。你根本不需要改变你的XML bean定义。 (如果你愿意,你可以*显式地*提供构造函数的参数,但只要这些bean是明确的,Spring就可以为你解决它。) – chrylis

+0

是的,我不需要改变任何东西。我只是认为在使用Spring时不需要在任何地方实例化bean。 – RK1