spring源码解析--bean生命周期

本文解析了Spring框架中bean的生命周期过程,包括初始化、依赖注入、切面编程(AOP)的集成,以及关键扩展点和后置处理器的作用。重点探讨了`finishBeanFactoryInitialization`方法和`@EnableAspectJAutoProxy`对AOP的影响。
摘要由CSDN通过智能技术生成

spring源码解读(三)bean生命周期

1 目的分析this.finishBeanFactoryInitialization(beanFactory); 方法,熟悉里面扩展点等。
2 为添加spring-aop我们对01-spring-ioc中的类进行补充,添加切面类(放在可以被被扫描的地方),并在App上添加@EnableAspectJAutoProxy 注解

@Component
@Aspect
public class MyAspectj {
    @Before("execution(* com.meituan.service.*.test(..))")
    public void before() {
        System.out.println("before--------------------------");
    }

}
//为AService添加注入
@Component
@Scope(proxyMode = ScopedProxyMode.NO)
public class AService {

    @Autowired
    private BService bService;

    public void test() {
        System.out.println("I am AService");
    }
}

@EnableAspectJAutoProxy 注解会将AspectJAutoProxyRegistrar导入,其实现了ImportBeanDefinitionRegistrar接口,会执行registerBeanDefinitions方法将org.springframework.aop.config.internalAutoProxyCreator 注入到容器

这里是在前面的refresh方法中的注入beanPostProcessor将bean后置处理器注入容器的(会将bd中实现了beanPostProcessor接口的bd实列化出来加入到bean后置处理器容器中)

3 进入protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) 方法
在这里插入图片描述
执行到这里,传入的是lamda表达式,存储在beanFactory的embeddedValueResolvers集合里

beanFactory.addEmbeddedValueResolver((strVal) -> {
                return this.getEnvironment().resolvePlaceholders(strVal);
            });
//符合函数式接口,strVal形参在实际调用的时候传入

进入preInstantiateSingletons()方法,我们暂时不讨论FactoryBean相关,按照一般bean查看初始化过程

在这里插入图片描述
在getbean这里我们在断点上设置beanName=AService,点击进这个方法,一层一层点击进去,到doGetBean方法

在这里插入图片描述
注意: 这里有一个this.getSingleton(beanName),这是第一去拿bean,点击进去到getSingleton方法中

在这里插入图片描述
可以看到这里先从单列池从去拿,很明显我们第一次过来拿到null,

然后判断是否是正确创建的bean,也不是所以直接返回null,这是我们第一次去拿bean,拿到null,单列池和和正在创建的bean集合都没有。

返回到doGetBean进行执行
在这里插入图片描述
这里会将当前bean的名字(字符串)设置进alreadyCreated集合中

然后判断是否有dependOn注解,有的话先去实列化别的,我们这里没有直接跳过

进入到单列创建
在这里插入图片描述
调用getSingleton,传入的是lamda表达式点进去看。
在这里插入图片描述
里面会有Object singletonObject = this.singletonObjects.get(beanName); 第二次直接去单列池拿,还是空

继续执行下面逻辑this.beforeSingletonCreation(beanName);这里会将当前beanname存入singletonsCurrentlyInCreation(单列正在创建)

singletonObject = singletonFactory.getObject(); 调用传入的lamda表达式执行,this.createBean(beanName, mbd, args);

在这里插入图片描述
进入createBean后,到断点处,进入此方法,这里会拿到所有的beanPostProcessor,调用里面实现了InstantiationAwareBeanPostProcessor接口的beanPostProcessor的InstantiationAwareBeanPostProcessor方法

1 这里是第一次调用bean后置处理器,当反悔的beanInstance不为空的时候就不会走bean的正常初始化流程,并且会调用postProcessAfterInitialization,并返回bean,可以自己实现InstantiationAwareBeanPostProcessor,返回自己设置的bean

第一个扩展点
在这里插入图片描述
继续执行,上一步拿到的是null,所以这里开始bean的创建了,进入断点方法

在这里插入图片描述
进入断点方法,开始创建bean,第2次调用后置处理器,决定以哪种方式创建bean对象,(先通过工厂创建;如果不能,使用构造方法;最后使用无参构造 )假如类中有多个构造方法,生效的优先级(@Autowired > autowireMode =3 > 无参构造)、

第二次扩展点
在这里插入图片描述
执行到这一步,开始构造器推测,也是通过执行BeanPostProcessor来的

在这里插入图片描述
点进方法,判断的是SmartInstantiationAwareBeanPostProcessor接口,执行determineCandidateConstructors方法,我们一个一个找,发现调用的是AutowiredAnnotationBeanPostProcessor类(他实现了SmartInstantiationAwareBeanPostProcessor接口)

在这里插入图片描述
返回到protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException 方法

在这里插入图片描述
我们实列化出来的对象通过包装类已经拿到了,有一个缓存操作,对于非单列的bean下次进来就可以不用执行构造器推测等操作,

3 第三次执行Bean后置处理器,允许后置处理器修改合并的bean定义 ,实现类 AutowiredAnnotationBeanPostProcessor,用于扫描 @Autowired和@Value修饰的属性和方法,封装到InjectionMetadata。

AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有@Autowired 注解时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去。会调用到AutowiredAnnotationBeanPostProcessor 的buildAutowiringMetadata()方法,buildAutowiringMetadata方法解析等待自动注入类的所有属性。它通过分析所有字段和方法并初始化org.springframework.beans.factory.annotation.InjectionMetadata类的实例来实现。在这里插入图片描述
继续执行

第4次调用后置处理器 提前暴露对象的引用到 singletonFactory 单例工厂中,解决循环引用的问题,提前将工厂对象放入缓存中
在这里插入图片描述
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);

这一行体现支持循环依赖,我们可以通过设置allowCircularReferences来不开启循环依赖

里面内容如下,添加进容器中
在这里插入图片描述
继续执行

第5次,第6次调用后置处理器 注入依赖在这里插入图片描述
我们点进this.populateBean(beanName, mbd, instanceWrapper);方法看看(这里有spring调用第五次和第六次后置处理器)

这里是第五次调用bean后置处理器,在目标对象实例化之后调用,此时对象被实例化,但是对象的属性还未设置。如果该方法返回

fasle,则会忽略之后的属性设置。返回true,按正常流程设置属性值在这里插入图片描述
继续向下,到第六次执行后置处理器

if (continueWithPropertyPopulation) {		//第五次bean后置处理器调用返回false就不执行了
                PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
                if (mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) {		//判断属性注入方式是否是by_name或者是by_type,这里是0默认注入方式,需要程序员手动注入,即添加Autowired注解
                																																									//才会注入,现在注解方式获取的bd里面的autowiredMode都是0,
                    MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
                    if (mbd.getResolvedAutowireMode() == 1) {
                        this.autowireByName(beanName, mbd, bw, newPvs);
                    }

                    if (mbd.getResolvedAutowireMode() == 2) {
                        this.autowireByType(beanName, mbd, bw, newPvs);
                    }

                    pvs = newPvs;
                }

                boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
                boolean needsDepCheck = mbd.getDependencyCheck() != 0;
                PropertyDescriptor[] filteredPds = null;
                if (hasInstAwareBpps) {
                    if (pvs == null) {
                        pvs = mbd.getPropertyValues();
                    }

                    Iterator var9 = this.getBeanPostProcessors().iterator();

                    while(var9.hasNext()) {
                    //第六次调用后置处理器,可以在该方法内对属性值进行修改(此时属性值还未设置,但可以修改原本会设置的进去的属性值)。
                        BeanPostProcessor bp = (BeanPostProcessor)var9.next();
                        if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        
                        	
                        	//处理 @Autowired 属性注入逻辑
                					// AutowiredAnnotationBeanPostProcessor.postProcessProperties
                					//InjectionMetadata#inject
                					//AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
                					//DefaultListableBeanFactory#resolveDependency
                					//DefaultListableBeanFactory#doResolveDependency
                					//DependencyDescriptor#resolveCandidate //此方法直接返回 beanFactory.getBean(beanName);
                          
                          
                            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                            PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
                            if (pvsToUse == null) {
                                if (filteredPds == null) {
                                    filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                                }

                                pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
                                if (pvsToUse == null) {
                                    return;
                                }
                            }

                            pvs = pvsToUse;
                        }
                    }
                }

                if (needsDepCheck) {
                    if (filteredPds == null) {
                        filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                    }

                    this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
                }
								//普通数据注入
                if (pvs != null) {
                    this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
                }

            }
        }

第6次调用后置处理器,用来处理Bean中 属性注入,包括 @Autowired 注入;此时如果存在循环引用的问题,也会一并处理掉(从单例工厂中获取属性bean,生成earlySingletonObject,添加到earlySingletonObjects中,解决循环依赖问题)

即Aservice需要注入Bservice,但是Bservice还没有初始化出来,这时候会去初始化Bservice,到需要注入Aservice的,能从单列工厂中拿到Aservice,,然后继续执行完剩下流程,调用返回,继续执行AService的后置处理,解决循环依赖

接下来进入第七次bean后置处理器和第八次后置处理器(spring aop基于第八次后置处理器的执行)

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(() -> {
                this.invokeAwareMethods(beanName, bean);
                return null;
            }, this.getAccessControlContext());
        } else {
        		//如果实现了aware借口会,向里面注入对应的属性
            this.invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) 
        		// 第七次执行后置处理器,主要与aware借口注入属性
            //  如果配置了@PostConstruct  会调用
            // InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        }

        try {
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
        }

        if (mbd == null || !mbd.isSynthetic()) {
        		//第八次执行bean后置处理器,
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

构造方法 > @Autowired (属性注入)> @PostContruct

8 接下来执行第八次bean后置处理器,这里会通过代理模式返回aop加强后的bean,默认是cglib
在这里插入图片描述
9 第九次执行后置处理器,标记单例bean为可销毁的,

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值