zoukankan      html  css  js  c++  java
  • Spring 源码学习 15:finishBeanFactoryInitialization(重点)

    前言

    可以说前面的都是准备工作,而接下来开始的才是重点,在这一步会完成 BeanFactory 的初始化,同时实例化单例 Bean。

    具体怎么操作的,那就一起阅读源码吧!

    不过在阅读源码之前,还是需要了解一些知识的。

    1. 什么是 FactoryBean ?
    2. FactoryBean 是如何使用的 ?
    3. Bean 是如何初始化的?
    4. 常说的循环依赖是怎么解决的?

    什么是 FactoryBean ?

    在官网的这篇文章《What's a FactoryBean?》中有相关解答,有兴趣的小伙伴可以看一下。

    由内部使用的对象实现的接口,这些对象 BeanFactory 本身就是单个对象的工厂。如果 bean 实现此接口,则它将用作对象公开的工厂,而不是直接用作将自身公开的 bean 实例。

    注意:实现此接口的 bean 不能用作普通 bean。 FactoryBean以 bean 样式定义,但是为 bean 引用(getObject())公开的对象始终是它创建的对象。

    FactoryBeans 可以支持单例和原型,并且可以按需延迟创建对象,也可以在启动时急于创建对象。

    当生命一个 FactoryBean 时,会存在两个类型的 Bean,分别是 FactoryBean 本身,以及它需要创建的类型的 Bean。

    下面是使用示例:

    使用

    1. PaidComponent

    public class PaidComponent {
    
    	public PaidComponent() {
    		System.out.println("PaidComponent 无参构造被调用");
    	}
    }
    

    2. PaidComponentFactoryBean

    @Component
    public class PaidComponentFactoryBean implements FactoryBean<PaidComponent> {
    
    	@Override
    	public PaidComponent getObject() throws Exception {
    
    		System.out.println("PaidComponentFactoryBean 的 getObject 方法被调用");
    
    		return new PaidComponent();
    	}
    
    	@Override
    	public Class<?> getObjectType() {
    		return PaidComponent.class;
    	}
    	
    }
    

    3 Test

    public class AnnotationConfigApplicationTest {
    
    	public static void main(String[] args) {
    
    		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    
    		context.register(JavaConfig.class);
    
    
    		context.refresh();
    
    
    		System.out.println(context.getBean("paidComponentFactoryBean"));
    		System.out.println(context.getBean("&paidComponentFactoryBean"));
    		System.out.println(context.getBean(PaidComponent.class));
    
    	}
    }
    
    

    可以看出注册了两个 Bean, 一个是 paidComponentFactoryBean ,另一个是 &paidComponentFactoryBean

    而直接获取 paidComponentFactoryBean 获取到的其实是 FactoryBean 的 getObject() 方法返回的类型。

    finishBeanFactoryInitialization 源码

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // Initialize conversion service for this context.
        // 初始化类型转换器
        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
            beanFactory.setConversionService(
                    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
        }
    
        // Register a default embedded value resolver if no bean post-processor
        // (such as a PropertyPlaceholderConfigurer bean) registered any before:
        // at this point, primarily for resolution in annotation attribute values.
        // 主要用于注释属性值的解析
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
        }
    
        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
        // 尽早初始化 LoadTimeWeaverAware Bean,以便尽早注册其转换器。
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }
    
        // Stop using the temporary ClassLoader for type matching.
        // 停止使用临时的ClassLoader进行类型匹配。
        beanFactory.setTempClassLoader(null);
    
        // Allow for caching all bean definition metadata, not expecting further changes.
        // 设置 beanDefinition 元数据 不可以再修改
        beanFactory.freezeConfiguration();
    
        // Instantiate all remaining (non-lazy-init) singletons.
        // 实例化单例 bean
        beanFactory.preInstantiateSingletons();
    }
    

    这里重点关注最后一行

    beanFactory.preInstantiateSingletons();

    preInstantiateSingletons

    这块进入的是类 DefaultListableBeanFactory 类的源码。

    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.
        // 将 beanDefinitionNames 放到集合中
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    
        // Trigger initialization of all non-lazy singleton beans...
        // 遍历
        for (String beanName : beanNames) {
            // 获取 bd 信息, 因为可能 定义了 parentBeanDefinition
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            // 非抽象, 单例, 且不是懒加载
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                // 判断是否为 FactoryBean
                if (isFactoryBean(beanName)) {
                    // FactoryBean 需要添加前缀 & ,通过 getBean(&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<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...
        // 如果 Bean 实现了 SmartInitializingSingleton,
        // 在这里会统一调用 afterSingletonsInstantiated 方法
        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<Object>) () -> {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }, getAccessControlContext());
                }
                else {
                    smartSingleton.afterSingletonsInstantiated();
                }
                smartInitialize.end();
            }
        }
    }
    

    上面方法中通过循环 beanNames 进行初始化 Bean。

    其中需要区别 BeanFactory 和 普通 Bean。 这也是我开始为什么先介绍了什么是 BeanFactory ?

    下面就需要重点关注 getBean(beanName) 方法。

    getBean

    public Object getBean(String name) throws BeansException {
        return doGetBean(name, null, null, false);
    }
    

    getBean 方法中调用的是 doGetBean 方法。

    doGetBean

    doGetBean 方法作用是:返回一个实例,该实例可以是指定bean的共享或独立的

    该方法接受四个参数:

    name – 要检索的 bean 的名称
    requiredType – 要检索的 bean 的必需类型,这个可以为空
    args –使用显式参数创建bean实例时要使用的参数(仅在创建新实例而不是检索现有实例时才应用)
    typeCheckOnly –是否为类型检查而不是实际使用获取实例

    protected <T> T doGetBean(
            String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
            throws BeansException {
    
        // 去掉工厂引用的前缀, 同时转换别名
        String beanName = transformedBeanName(name);
        Object bean;
    
        // Eagerly check singleton cache for manually registered singletons.
        // 从缓存中检查单例是否已经存在
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            if (logger.isTraceEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                            "' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            // 从缓存中如果获取到了, 普通 Bean 直接返回, FactoryBean 则返回 FactoryBean 创建的 Bean
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
    
        else {
            // Fail if we're already creating this bean instance:
            // We're assumably within a circular reference.
            // 返回指定的 原型bean (prototype 类型的 Bean) 是否当前正在创建中(在当前线程内)。
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }
    
            // Check if bean definition exists in this factory.
            // 检查 BeanFactory 是否存在这个 Bean 的 BeanDefinition
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                // 检查父容器中有没有定义
                String nameToLookup = originalBeanName(name);
                // 返回从父容器中查询的结果
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                            nameToLookup, requiredType, args, typeCheckOnly);
                }
                else if (args != null) {
                    // Delegation to parent with explicit args.
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else if (requiredType != null) {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
                else {
                    return (T) parentBeanFactory.getBean(nameToLookup);
                }
            }
    
            if (!typeCheckOnly) {
                // 将当前 beanName 放入一个 alreadyCreated 的 Set 集合中。
                // 标识本次调用方法,并非是要获取bean的类型,而是为了创建实例,将beanName存到alreadyCreated集合,代表该bean已经创建了,后面try。。catch有异常会清空该beanName
                markBeanAsCreated(beanName);
            }
    
            StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
                    .tag("beanName", name);
            try {
                if (requiredType != null) {
                    beanCreation.tag("beanType", requiredType::toString);
                }
                // 获取 Bean 的 BeanDefinition
                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);
    
                // Guarantee initialization of beans that the current bean depends on.
                // 确保依赖的 Bean 已经被初始化, 比如 @DependsOn 注解
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        registerDependentBean(dep, beanName);
                        try {
                            // 创建依赖的 Bean
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }
    
                // Create bean instance.
                if (mbd.isSingleton()) {
                    // 单例 bean
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            // Explicitly remove instance from singleton cache: It might have been put there
                            // eagerly by the creation process, to allow for circular reference resolution.
                            // Also remove any beans that received a temporary reference to the bean.
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
                // 创建原型Bean
                else if (mbd.isPrototype()) {
                    // It's a prototype -> create a new instance.
                    Object prototypeInstance = null;
                    try {
                        beforePrototypeCreation(beanName);
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                        afterPrototypeCreation(beanName);
                    }
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }
    
                else {
                    // 委托给实现类处理
                    String scopeName = mbd.getScope();
                    if (!StringUtils.hasLength(scopeName)) {
                        throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
                    }
                    Scope scope = this.scopes.get(scopeName);
                    if (scope == null) {
                        throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                    }
                    try {
                        Object scopedInstance = scope.get(beanName, () -> {
                            beforePrototypeCreation(beanName);
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            finally {
                                afterPrototypeCreation(beanName);
                            }
                        });
                        bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    }
                    catch (IllegalStateException ex) {
                        throw new ScopeNotActiveException(beanName, scopeName, ex);
                    }
                }
            }
            catch (BeansException ex) {
                beanCreation.tag("exception", ex.getClass().toString());
                beanCreation.tag("message", String.valueOf(ex.getMessage()));
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
            finally {
                beanCreation.end();
            }
        }
    
        // Check if required type matches the type of the actual bean instance.
        // 检查所需的类型是否与实际bean实例的类型匹配。
        if (requiredType != null && !requiredType.isInstance(bean)) {
            try {
                T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
                if (convertedBean == null) {
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
                return convertedBean;
            }
            catch (TypeMismatchException ex) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Failed to convert bean '" + name + "' to required type '" +
                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }
    

    上面代码比较长,基本上步骤已经添加相应的注释,基本上可以分为三步:

    1. 从缓存中获取到 Bean,创建对应的 Bean;
    2. 没有从缓存中获取到 Bean,创建对应的 Bean;
    3. 检查所需的类型是否与实际bean实例的类型匹配。

    下面从这三个步骤分别介绍:

    • 从缓存中获取到 Bean,创建对应的 Bean

    Object sharedInstance = getSingleton(beanName);

    public Object getSingleton(String beanName) {
        return getSingleton(beanName, true);
    }
    /**
     * 返回以给定名称注册的(原始)单例对象。
     *
     * 检查已经实例化的单例,并允许早期引用当前创建的单例(解析循环引用)
     */
    @Nullable
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // Quick check for existing instance without full singleton lock
        // private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
        // 缓存了 单例 Bean
        Object singletonObject = this.singletonObjects.get(beanName);
        // 如果没有获取到, 并且当前 Bean 正在被创建中
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            // private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
            // 早期的单例对象, 先从 earlySingletonObjects 中获取
            singletonObject = this.earlySingletonObjects.get(beanName);
            // 没有从 earlySingletonObjects 缓存中获取到
            if (singletonObject == null && allowEarlyReference) {
                synchronized (this.singletonObjects) {
                    // Consistent creation of early reference within full singleton lock
                    // 再次获取并检查
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        singletonObject = this.earlySingletonObjects.get(beanName);
                        if (singletonObject == null) {
                            // private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
                            // 从 singletonFactories 缓存中获取
                            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                            if (singletonFactory != null) {
                                singletonObject = singletonFactory.getObject();
                                // 添加到 earlySingletonObjects 缓存中
                                this.earlySingletonObjects.put(beanName, singletonObject);
                                // 从 singletonFactories 缓存中删除
                                this.singletonFactories.remove(beanName);
                            }
                        }
                    }
                }
            }
        }
        return singletonObject;
    }
    

    这里可以看出,获取一个 Bean :

    1. 先从 singletonObjects 中获取 Bean;
    2. 获取不到,从 earlySingletonObjects 中获取 Bean;
    3. 获取不到,从 singletonFactories 中获取 Bean。

    当然这一块涉及到循环引用,篇幅有限,后面会专门介绍循环引用。

    • 没有从缓存中获取到 Bean,创建对应的 Bean
    // Create bean instance.
    if (mbd.isSingleton()) {
        // 单例 bean
        sharedInstance = getSingleton(beanName, () -> {
            try {
                return createBean(beanName, mbd, args);
            }
            catch (BeansException ex) {
                // Explicitly remove instance from singleton cache: It might have been put there
                // eagerly by the creation process, to allow for circular reference resolution.
                // Also remove any beans that received a temporary reference to the bean.
                destroySingleton(beanName);
                throw ex;
            }
        });
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    } else if (mbd.isPrototype()) {
        // 创建原型Bean
        
    } else {
        // 委托给实现类处理
        String scopeName = mbd.getScope();
    }
    
    • 检查所需的类型是否与实际bean实例的类型匹配

    总结

    这里主要介绍了 Bean 的创建过程,主要是对整个过程有个大概的了解和熟悉,针对过程画图如下:

    其中 Bean 的实例化主要关注单例 Bean 的实例化,后面准备对其进行详细研究后,再进行说明。

    相关推荐

  • 相关阅读:
    107. Binary Tree Level Order Traversal II
    103. Binary Tree Zigzag Level Order Traversal
    102. Binary Tree Level Order Traversal
    690. Employee Importance
    1723. Find Minimum Time to Finish All Jobs
    LeetCode 329 矩阵中最长增长路径
    7.2 物理内存管理
    LeetCode 面试题 特定深度节点链表
    LeetCode 100 相同的树
    npm安装包命令详解,dependencies与devDependencies实际区别
  • 原文地址:https://www.cnblogs.com/liuzhihang/p/source-spring-15.html
Copyright © 2011-2022 走看看