lazy-init 延迟加载机制

lazy-init 延迟加载机制分析

普通 Bean 的初始化是在容器启动初始化阶段执行的,而被lazy-init=true修饰的 bean 则是在从容器里第一次进行context.getBean() 时进行触发。Spring 启动的时候会把所有bean信息(包括XML和注解)解析转化成Spring能够识别的BeanDefinition并存到Hashmap里供下面的初始化时用,然后对每个BeanDefinition 进行处理,如果是懒加载的则在容器初始化阶段不处理,其他的则在容器初始化阶段进行初始化并依赖注入。

  • 容器初始化时候对延迟加载的处理
public void preInstantiateSingletons() throws BeansException {
    if (logger.isTraceEnabled()) {
        logger.trace("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.
     */
    // 所有beanDefinition集合
    List beanNames = new ArrayList<>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    // 触发所有非懒加载单例bean的初始化
    for (String beanName : beanNames) {
        // 获取bean 定义
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        // 判断是否是懒加载单例bean,如果是单例的并且不是懒加载的则在容器创建时初始化
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            // 如果是 factoryBean 则加 &
            if (isFactoryBean(beanName)) {
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                if (bean instanceof FactoryBean) {
                    FactoryBean factory = (FactoryBean) bean;
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged(
                                (PrivilegedAction) ((SmartFactoryBean) factory)::isEagerInit,
                                getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
            }
            else {
                /*
                实例化bean
                如果是普通bean则进行初始化并依赖注入,此 getBean(beanName)接下来触发的逻辑
                和懒加载时 context.getBean("beanName") 所触发的逻辑是一样的
                */
                getBean(beanName);
            }
        }
    }

    // Trigger post-initialization callback for all applicable beans...
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction) () -> {
                    smartSingleton.afterSingletonsInstantiated();
                    return null;
                }, getAccessControlContext());
            }
            else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}
 
 
  • 懒加载获取bean的流程
总结:懒加载的bean,是在获取的时候,才进行创建bean

你可能感兴趣的:(lazy-init 延迟加载机制)