spring到底什麼時候進行bean實例化

這個問題看似簡單實則坑多。

  • 1、很早以前有人告訴我說,spring是在你使用該bean的時候,通過動態代理給你實例化出來的。
  • 2、後來又有人告訴我說,spring是在容器啓動的時候就將bean都給你實例化好了。

那麼究竟哪個正確呢?其實這麼回答都不正確,spring對bean的初始化其實是有條件的。
首先判斷是單例還是多例,如果是多例的情況下,肯定是在你第一次使用該bean的時候初始化無疑。
但是如果是單例的情況下又分爲兩種情況:

  • 一是當你lazy-init懶加載設置爲true時是在你第一次使用的時候實例化;第一次使用包括的範圍是此對象被其它bean引用也算第一次使用,所以即使你設置lazy-initture只要你的此bean被引用或者注入也會被初始化。
  • 二是lazy-init懶加載爲false時(這也是spring默認值)是在spring容器啓動時進行實例化。

以下我們來看下spring實例化bean的源碼你就知道了
查看AbstractApplicationContext.refresh()方法中實例化所有非懶加載的bean過程即
這個方法finishBeanFactoryInitialization查看此方法最後一行beanFactory.preInstantiateSingletons();實際調用此方法我們來看此單例實例化過程
DefaultListBeanFactory.preInstantiateSingletons源碼如下

public void preInstantiateSingletons() throws BeansException {
//此處省略無數行代碼。。。。。
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//此處做出了判斷必須是非抽象的並且必須是單例的並且必須是非懶加載的。
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				//此處省略無數行代碼
		}

	}
	//此處省略無數行代碼
}

從以上代碼的循環中的條件我們不難看出容器啓動過程中會實例化的bean只有滿足以下三個條件的bean

  • 非抽象的
  • 單例的
  • 非懶加載的
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章