1. 程式人生 > >(一)Spring IoC原始碼-3.其他特性的實現原理-01lazy-init與預例項化

(一)Spring IoC原始碼-3.其他特性的實現原理-01lazy-init與預例項化

前面的文章也提到過,IOC容器初始化過程一般不包含Bean載入的實現。Bean載入一般發生在應用第一次通過getBean向容器索取Bean的時候。但有一個例外:如果在XML檔案中為Bean定義了lazy-init屬性,那麼Bean的載入在IOC容器初始化時就預先完成了,我們將其稱為預例項化。預例項化雖然會對容器初始化的效能有一些影響,但卻能夠提高應用第一次取得Bean的效能。

在上下文的初始化過程中,也就是refresh中的程式碼實現,可以看到預例項化是整個refresh初始化IoC容器的一個步驟。在AbstractApplicationContext中看一下refresh的實現。

@Override
public void refresh() throws BeansException, IllegalStateException { ... ... // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); ... ... } protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { ... ... beanFactory.preInstantiateSingletons(); ... ... }

在finishBeanFactoryInitialization的方法中,封裝了對lazy-init屬性的處理,實際的處理是在DefaultListableBeanFactory這個基本容器的preInstantiateSingletons方法中完成的。

@Override
public void preInstantiateSingletons() throws BeansException {
    if (this.logger.isDebugEnabled()) {
        this.logger.debug("Pre-instantiating singletons in "
+ this); } // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... 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((PrivilegedAction<Boolean>) () -> ((SmartFactoryBean<?>) factory).isEagerInit(), getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } else { getBean(beanName); } } } // Trigger post-initialization callback for all applicable beans... for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }