bean懶載入
阿新 • • 發佈:2019-02-20
Indicates whether or not this bean is to be lazily initialized.
If false, it will be instantiated on startup by bean factories
that perform eager initialization of singletons. The default is
"false".
bean如果配置lazy-init=”true”時,則在容器初始化過程中不會執行依賴注入,而當使用時才會去初始化bean,真的是這樣麼?下面就是深入原始碼探究,會分析以下三種情況:
1. bean A沒有引用任何其他bean,且配置成懶載入
2. bean A引用了bean B,且bean A配置成懶載入
3. bean A引用了bean B,bean A沒有配置為懶載入,bean B配置為懶載入
首先程式碼入口還是AbstractApplicationContext#refresh
AbstractApplicationContext#finishBeanFactoryInitialization
方法中會執行DefaultListableBeanFactory#preInstantiateSingletons
:
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
關鍵程式碼是!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()
,會判斷bean是否為抽象類、單例、懶載入,如果不符合就不會執行if裡的程式碼,其實第一、二中情況都不符合的,所以不會執行到if語句裡的程式碼.關鍵是第三種情況,分析思路之前這篇(https://mp.weixin.qq.com/s/gduv_fAgB4-T13f6vsxkNw)分析是一樣的,也就是在建立bean A的時候,在例項化其屬性時,會建立bean B,有興趣的朋友可以打斷點除錯,以下總結:
1. bean配置lazy-init=”true”時,在容器初始化時不會建立該bean
2. 若一為單例且非懶載入的bean A引用了懶載入bean B時,在bean A被建立時,會建立bean B
3. 非單例或為抽象類或配置lazy-init=”true”的bean,都不會在容器初始化時建立bean
更多文章請關注微信公眾號: