写点什么

Spring 源码学习 15:finishBeanFactoryInitialization(重点)

发布于: 2021 年 01 月 19 日

前言


可以说前面的都是准备工作,而接下来开始的才是重点,在这一步会完成 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


@Componentpublic 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);}/** * 返回以给定名称注册的(原始)单例对象。 * * 检查已经实例化的单例,并允许早期引用当前创建的单例(解析循环引用) */@Nullableprotected 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 的实例化,后面准备对其进行详细研究后,再进行说明。


相关推荐



发布于: 2021 年 01 月 19 日阅读数: 19
用户头像

个人公众号:『 程序员小航 』 2020.07.30 加入

某不知名互联网公司 Java 程序员一枚。记录工作学习中的技术、开发及源码笔记;分享生活中的见闻感悟。

评论

发布
暂无评论
Spring 源码学习 15:finishBeanFactoryInitialization(重点)