1. 程式人生 > >@Autowired寫在變數上和構造器上的區別

@Autowired寫在變數上和構造器上的區別

  • @autowired可以寫在變數和構造器上,注入bean,但是有的時候寫在變數上會報空指標異常NPE,然後通過寫在構造器上就解決了此問題,如下所示:
    這種方式會報錯
public class Test{
    @Autowired
    private A a;

    private final String prefix = a.getExcelPrefix();

........
}

這樣寫就不報錯了

public class Test{
    private final String prefix;

    @Autowired
    public Test
(A a) { this.prefix= a.getExcelPrefix(); } ........ }
  • 其實這兩種方式都可以使用,但報錯的原因是載入順序的問題,@autowired寫在變數上的注入要等到類完全載入完,才會將相應的bean注入,而變數是在載入類的時候按照相應順序載入的,所以變數的載入要早於@autowired變數的載入,那麼給變數prefix 賦值的時候所使用的a,其實還沒有被注入,所以報空指標,而使用構造器就在載入類的時候將a載入了,這樣在內部使用a給prefix 賦值就完全沒有問題。

  • 如果不適用構造器,那麼也可以不給prefix 賦值,而是在接下來的程式碼使用的地方,通過a.getExcelPrefix()進行賦值,這時的對a的使用是在類完全載入之後,即a被注入了,所以也是可以的。

  • 總之,@Autowired一定要等本類構造完成後,才能從外部引用設定進來。所以@Autowired的注入時間一定會晚於建構函式的執行時間。但在初始化變數的時候就使用了還沒注入的bean,所以導致了NPE。若果在初始化其它變數時不使用這個要注入的bean,而是在以後的方法呼叫的時候去賦值,是可以使用這個bean的,因為那時類已初始化好,即已注入好了。