2016-03-07 52 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