首頁 > 軟體

聊一聊new物件與Spring對bean的初始化的差別

2022-02-25 13:01:38

new物件與Spring對bean初始化差別

這個問題是一次我將老系統程式碼遷移到基於Spring構建的新系統中時遇到的,老程式碼中有很多地方使用了new方法來初始化物件,當時也沒有特別注意,最後聯調的時候發現所有new出來的物件中使用Autowired自動依賴注入的屬性全都丟擲了NullPointerException。

什麼意思呢?

@Component
Class A {
    ...
} 
@Component
Class B {
    ...
} 
@Component
Class C {
    @Autowired
    A a;
    @Autowired
    B b;
} 

當我使用C c = new C()時,c中的a和b都是null,也就是無法完成注入。

說實話,在聯調的那一刻我有一瞬間是懵逼的,但現在回想起來,哦,真是太傻了。

簡單來理解

Spring首先會通過new方法建立一個物件,然後去完成屬性的填充,而這種填充在我們外界看來是“自動”的;而我們直接通過new方法建立物件時,是沒有誰去完成屬性的填充的,因而內部屬性值全為null。 

Spring類的注入和new簡單理解

springboot

  • main.run方法進入
  • refreshContext
  • refresh
  • finishBeanFactoryInitialization(完成beanFactory的初始化)
  • preInstantiateSingletons(初始化單例)
  • getBean(獲取Bean)
  • doGetBean
  • createBean
  • doCreateBean(此方法內部會createBean,建立bean即構造方法執行)
  • populateBean(進行autowired自動注入)
  • applyPropertyValues(進行屬性注入)

PS:new物件,不能導致物件依賴的注入屬性自動賦值,只有對物件進行注入,物件依賴的注入屬性才能賦值;

且注入的屬性不能在建構函式中操作,因為bean沒有建立完成,屬性也沒有注入,此時是為null的

問題:spring預設是單例模式,還有必要建立單例類嗎?

自己理解:有必要,如果不使用autowired進行自動注入,使用new操作還是可以生成多個物件,

spring的單例是針對自動注入

例子:

     @Component
     public class CxfClient{undefined
          @Value("${address }")
          private String address;
          private CxfClient(){undefined
               System.out.println(address ); //此時為null.bean沒有載入完成,屬性也沒有載入
          }
          public void createClient(){undefined
               System.out.println(address );//此時為組態檔中的值
          }
          private static class SingletonHolder {undefined
              private static final CxfClient INSTANCE = new CxfClient();
          }
          public static final CxfClient getInstance() {undefined
               return SingletonHolder.INSTANCE;
          }
     }
     public class Test{undefined
          @Autowired
          private CxfClient cxfClient;
          public void testClient(){undefined
               CxfClient.getInstance().createClient();//列印為null.無法注入
               cxfClient.createClient();//列印為組態檔中的值
          }
     }

      

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com