(一)Spring IoC源码-3.其他特性的实现原理-01lazy-init与预实例化

版权声明:本文版权归作者所有,欢迎转载。转载时请在文章明显位置给出作者名字(潘威威)及原文链接。请勿将本文用于任何商业用途。 https://blog.csdn.net/panweiwei1994/article/details/80499794

本文已收录于【Spring源码札记专栏】

前面的文章也提到过,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();
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/panweiwei1994/article/details/80499794