Spring-创建非懒加载的单例Bean源码

补充:关于扫描的逻辑

/**
 * Scan the class path for candidate components.
 * @param basePackage the package to check for annotated classes
 * @return a corresponding Set of autodetected bean definitions
 */
public Set findCandidateComponents(String basePackage) {
    if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
        return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
    }
    else {
        return scanCandidateComponents(basePackage); // 大部分情况是这一种
    }
}

其中大部分情况是下面一种。上面这种的componentsIndex是为了提高扫描效率

Spring-创建非懒加载的单例Bean源码_第1张图片

当配置了spring.components文件(文件内容不为空),才会走上面的componentsIndex逻辑。

spring.components文件内容示例:(相当于告诉Spring要去扫描哪些Bean)

com.gax.service.UserService=org.springframework.stereotype.Component
#com.gax.service.OrderService=org.springframework.stereotype.Component

注意:以上配置的类上面仍然需要添加@Component,不添加会报Bean找不到的异常

实例化非懒加载的单例Bean源码:

// 遍历、合并、创建非懒加载单例Bean
@Override
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.
    List beanNames = new ArrayList<>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    for (String beanName : beanNames) {
        // 获取合并后的BeanDefinition
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

        // 非懒加载的单例Bean,注意这里是抽象的BeanDefinition,和抽象类区分开
        //  抽象的BeanDefinition
        // 抽象的BeanDefinition不能生成Bean,但是可以给其他Bean当父BeanDefinition
        // 
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {
                // 获取FactoryBean对象
                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) {
                        // 创建真正的Bean对象(getObject()返回的对象)
                        getBean(beanName);
                    }
                }
            }
            else {
                // 创建Bean对象
                getBean(beanName);
            }
        }
    }
    
    // 所有的非懒加载单例Bean都创建完了后
    // Trigger post-initialization callback for all applicable beans...
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
                .tag("beanName", beanName);
            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction) () -> {
                    smartSingleton.afterSingletonsInstantiated();
                    return null;
                }, getAccessControlContext());
            }
            else {
                smartSingleton.afterSingletonsInstantiated();
            }
            smartInitialize.end();
        }
    }
}

注意:抽象的BeanDefinition和抽象类的区别。思考抽象的BeanDefinition有什么用?

getMergedLocalBeanDefinition合并BeanDefinition是什么意思?

这个方法非常重要,合并之后的BeanDefinition。合并属性等信息:自己定义了用自己的,自己没定义用父亲的

对于父子BeanDefinition,合并是生成一个新的BeanDefinition,原来的父子BeanDefinition不变,把合并后的属性添加给新的BeanDefinition。子BeanDefinition的属性覆盖父BeanDefinition的属性,这就是合并

合并后的BeanDefinition放在mergedBeanDefinitions里面,很重要

afterSingletonsInstantiated方法什么时候调用的?

所有的非懒加载单例Bean创建完之后,才会调用每个单例Bean的afterSingletonsInstantiated方法

isFactoryBean(beanName)方法,也很重要,很多地方有用到

@Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
    String beanName = transformedBeanName(name);
    Object beanInstance = getSingleton(beanName, false);
    if (beanInstance != null) {
        return (beanInstance instanceof FactoryBean);
    }
    // No singleton instance found -> check bean definition.
    if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
        // No bean definition found in this factory -> delegate to parent.
        return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
    }
    return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}

/**
 * Check whether the given bean is defined as a {@link FactoryBean}.
 * @param beanName the name of the bean
 * @param mbd the corresponding bean definition
 */
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
    Boolean result = mbd.isFactoryBean;
    if (result == null) {
        // 根据BeanDefinition推测Bean类型(获取BeanDefinition的beanClass属性)
        Class beanType = predictBeanType(beanName, mbd, FactoryBean.class);
        // 判断是不是实现了FactoryBean接口
        result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
        mbd.isFactoryBean = result;
    }
    return result;
}

你可能感兴趣的:(spring,java)