SpringBoot源码分析

本文详细解析Spring框架中Bean的创建与初始化过程,包括Bean的注册、实例化、属性填充、初始化方法调用及销毁等关键步骤。深入探讨了Bean的生命周期管理,以及Spring如何处理循环依赖和依赖注入。

Spring中Bean的创建

Bean注册的总体流程

在这里插入图片描述
BeanDefinationReader读取从xml文件中读取配置并构建BeanDefiniton,然后基于别名(id作为key注册到BeanDefinitionRegister注册器,name作为key注册到AliasRegistry注册中心)注册到BeanDefinitonRegister中。

Bean创建时序图

在这里插入图片描述
1、调用BeanFacatory.getBean()会触发Bean的实例化
2、DefaultSingletonBeanRegistry中缓存了单例Bean
3、如果没有缓存,则通过AbstractAutowireCapableBeanFactory的createBean方法创建对象(默认利用无参构造器+反射创建)

构造单例Bean的方法

1、AbstractBeanFactory.doGetBean

//AbstractBeanFactory.doGetBean
//判断是否有其他依赖,如果有其他依赖,注册依赖的 bean 并调用 getBean() 方法创建
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);
             getBean(dep);
         }
     }

-> DefaultSingletonBeanRegistry.getSingleton(获取缓存的Bean)
-> singletonFactory.getObject()(没有缓存就创建Bean,即调用createBean方法)
-> AbstractAutowireCapableBeanFactory.createBean

//AbstractBeanFactory.doGetBean
//实现singletonFactory.getObject()匿名内部类
if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}

-> AbstractAutowireCapableBeanFactory.doCreateBean
-> AbstractAutowireCapableBeanFactory.createBeanInstance


protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException {
 
    BeanWrapper instanceWrapper = null;
    // 1. 如果是单例,尝试获取对应的BeanWrapper
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
 
    // 2. bean未实例化,创建 bean 实例
    if (instanceWrapper == null) {
        /*
         * 说明对应的bean还没有创建,用对应的策略(工厂方法、构造函数)创建bean实例,以及简单初始化
         *
         * 将beanDefinition转成BeanWrapper,大致流程如下:
         * 1. 如果存在工厂方法,则使用工厂方法初始化
         * 2. 否则,如果存在多个构造函数,则根据参数确定构造函数,并利用构造函数初始化
         * 3. 否则,使用默认构造函数初始化
         */
        instanceWrapper = this.createBeanInstance(beanName, mbd, args);
    }
    // 从BeanWrapper中获取包装的bean实例
    final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
    // 从BeanWrapper获取包装bean的class引用
    Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
    mbd.resolvedTargetType = beanType;
 
    // 3. 应用 MergedBeanDefinitionPostProcessor,即执行后置处理器中的MergedBeanDefinitionPostProcessor处理器
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                // 处理 merged bean,Autowired通过此方法实现诸如类型的解析
                this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            } catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
        }
    }
 
    // 4. 检查是否需要提前曝光,避免循环依赖,条件:单例 && 允许循环依赖 && 当前bean正在创建中
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isDebugEnabled()) {
            logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
        }
        // 为避免循环依赖,在完成bean实例化之前,将对应的ObjectFactory加入bean的工厂
        this.addSingletonFactory(beanName, new ObjectFactory<Object>() {
            @Override
            public Object getObject() throws BeansException {
                // 对bean再一次依赖引用,应用SmartInstantiationAwareBeanPostProcessor
                return getEarlyBeanReference(beanName, mbd, bean);
            }
        });
    }
//说明一下方法中各个变量的意义
//singletonObjects:用于保存 beanName 和 bean 实例之间的关系
//singletonFactories:用于保存 beanName 和创建 bean 的工厂之间的关系
//earlySingletonObjects:也是保存 beanName 和 bean 实例之间的关系,不同于 singletonObjects,当一个bean的实例放置于其中后,当bean还在创建过程中就可以通过 getBean 方法获取到
//registeredSingletons:用来保存当前所有已注册的 bean
 
    // 5. 初始化bean实例
    Object exposedObject = bean;
    try {
        // 对bean进行填充,将各个属性值注入,如果存在依赖的bean则进行递归初始化
        this.populateBean(beanName, mbd, instanceWrapper);
        if (exposedObject != null) {
            // 初始化bean,调用初始化方法,比如init-method
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        }
    } catch (Throwable ex) {
        if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
            throw (BeanCreationException) ex;
        } else {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
        }
    }
 
    // 6. 再次基于依存关系验证是否存在循环依赖
    if (earlySingletonExposure) { // 提前曝光
        Object earlySingletonReference = this.getSingleton(beanName, false);
        if (earlySingletonReference != null) { // 只有在检测到循环引用的情况下才会不为null
            if (exposedObject == bean) {  // exposedObject没有在初始化中被增强
                exposedObject = earlySingletonReference;
            } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
                // 获取依赖的bean的name
                String[] dependentBeans = this.getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    // 检测依赖,记录未完成创建的bean
                    if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                /*
                 * 因为bean在创建完成之后,其依赖的bean一定是被创建了的
                 * 如果actualDependentBeans不为空,则说明bean依赖的bean没有完成创建,存在循环依赖
                 */
                if (!actualDependentBeans.isEmpty()) {
                    throw new BeanCurrentlyInCreationException(beanName,
                            "Bean with name '" + beanName + "' has been injected into other beans [" +
                                    StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                    "] in its raw version as part of a circular reference, but has eventually been " +
                                    "wrapped. This means that said other beans do not use the final version of the " +
                                    "bean. This is often the result of over-eager type matching - consider using " +
                                    "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }
    try {
        // 7. 注册DisposableBean
        this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }
 
    return exposedObject;

Bean相关方法执行顺序

(1)实例化Bean
(CreateBean方法中调用resolveBeforeInstantiation)
//bean实例化前调用,是对bean定义进行修改的最后机会
1、InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation()方法

(doCreateBean方法中调用createBeanInstance)
2、构造方法–createBeanInstance()

(doCreateBean方法中调用populateBean)
3、populateBean属性注入

4.1、MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(mbd, beanType, beanName)

4、InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation()方法----在createBeanInstance方法之后,populateBean方法中

5、InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues()方法,用来改变bean的属性(这个时候属性值还未被设置,但是我们可以修改原本该设置进去的属性值,postProcessAfterInstantiation如果返回false,则不执行,@Value的实现)

(2)初始化Bean(doCreateBean方法中调用instantiateBean)
6、BeanPostProcessor后置处理器的before–initializeBean>applyBeanPostProcessorsBeforeInitialization

(instantiateBean中的invokeInitMethods方法)
7、InitializingBean–invokeInitMethods>InitializingBean.afterPropertiesSet()

(instantiateBean中的invokeInitMethods方法)
8、init-method(@Bean(initMethod=“init”))–invokeInitMethods>invokeCustomInitMethod

// bean实例化后立即调用,位于属性注入之前
9、BeanPostProcessor后置处理器的after–initializeBean>applyBeanPostProcessorsAfterInitialization

10、DisposableBean接口实现的destroy()方法

11、DefaultSingletonBeanRegistry.destroySingleton销毁bean

Spring@ConditionalOnXX注解

@ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean)

@ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean)

@ConditionalOnExpression(当表达式为true的时候,才会实例化一个Bean)

@ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean)该注解表示,如果存在它修饰的类的bean,则不需要再创建这个bean;可以给该注解传入参数例如@ConditionOnMissingBean(name = “example”),这个表示如果name为“example”的bean存在,这该注解修饰的代码块不执行。

@ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean)

@ConditionalOnNotWebApplication(不是web应用)

@ConditionalOnProperty(当有配置信息时生效)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值