概述
1.实例化前推断构造方法
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean
创建了一个 BeanWrapper对象用来报装实例化的bean
开始实例化
instanceWrapper = createBeanInstance(beanName, mbd, args);
跟进去
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance
获取bean的class类型
Class<?> beanClass = resolveBeanClass(mbd, beanName);
如果bean指定了工厂方法,将会进这个if判断
底层会获取工厂方法【静态工厂方法|实例化方法】--> 然后解析方法入参 --> 然后执行反射调用创建实例 --> 封装为包装对象返回.
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
如果bean是原型,将走这个分支
如果不是原型bean,将执行推断构造方法的方法
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
现在正在实例化的是bean A 没有显示提供构造方法,将默认提供一个无参构造 但是spring没有推断出任何构造方法
接着调用getPreferredConstructors,获取默认的构造方法
ctors = mbd.getPreferredConstructors();
结果还是什么都没拿到 最终调用 instantiateBean 方法
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
走到这里的条件 没有创建bean的回调方法 && 没有工厂方法 && 构造函数的参数未解析完毕 && 没有预先指定的默认构造函数
跟进 instantiateBean方法
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
先看下返回的实例化策略是什么
默认的创建策略为:CglibSubclassingInstantiationStrategy
2.实例化bean
跟进 org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate
拿到bean的class对象,获取默认的构造方法,将获取到的构造函数设置到bd中,最后调用 BeanUtils.instantiateClass(constructorToUse),并把构造方法传过去了
来到 org.springframework.beans.BeanUtils.instantiateClass
在BeanUtils.instantiateClass方法中 开启暴力反射,最终构造方法对象调用newInstance方法完成实例化
可以看到已经实例化出来了
回到 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean方法
2.1 调用bean的MergedBeanDefinitionPostProcessor 后期处理器
再次调用bean的后期处理器,此时bean已经实例化了,但没有完成属性注入
依次调用所有MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法,用来处理类中使用注解标注的属性,并放入到缓存中.
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
3.Bean实例化后,添加到三级缓存
往下继续走,看到又有一个三连判断
当前bean是否是单例,是否允许循环依赖,是否是正在创建的,都满足继续往下走
调用addSingletonFactory 参数又有一个lombad表达式,用的非常多
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
跟进去
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.addSingletonFactory
`如果当前的单实例缓存池中还没有beanName对应的单实例bean,
!this.singletonObjects.containsKey(beanName)
将lombad表达式放到三级缓存中,
this.singletonFactories.put(beanName, singletonFactory);
并从二级缓存中除beanName对应的bean实例
this.earlySingletonObjects.remove(beanName);
`将当前的beanName保存到已经注册的bean对应的Set集合中,标识其已经注册过
this.registeredSingletons.add(beanName);
回到addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
看下重写方法做了什么事情 注意此时没有调用
获取所有的后置处理器判断是不是实现了SmartInstantiationAwareBeanPostProcessor接口挨个调用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference Spring解决AOP代理对象的循环依赖问题的核心
接着doCreateBean方法往下看,紧接着调用了populateBean(beanName, mbd, instanceWrapper) 开始进入属性填充阶段
4.实例化后的InstantiationAwareBeanPostProcessor后置处理
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean
实例化后调用 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()方法
看过上篇博文知道在实例化前也调用了InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
如果我们重写了 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()方法,并且返回false,将不会进行属性填充,默认是true
`获取当前正在实例化的bean的所有属性
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
判断属性填充的方法 @Autowired既不属于ByName也不属于ByType
当前bean是否有InstantiationAwareBeanPostProcessor类型的后置处理器
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
依赖检测
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
如果有InstantiationAwareBeanPostProcessor类型的后置处理器 将进入if判断逻辑,执行后置处理器方法
5.属性填充阶段
真正的属性填充方法applyPropertyValues(beanName, mbd, bw, pvs);
applyPropertyValues(beanName, mbd, bw, pvs);
跟进applyPropertyValues
最终通过反射调用setter方法属性填充
6.初始化前执行三个aware回调方法
回到 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean 方法
属性填充完毕后立马执行初始化方法
接着看初始化方法
exposedObject = initializeBean(beanName, exposedObject, mbd);
跟进去
调用了三个aware回调方法 BeanNameAware -> BeanClassLoaderAware -> BeanFactoryAware
执行完三个回调方法后,调用 applyBeanPostProcessorsBeforeInitialization 又是一个后置处理器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
7.初始化前执行BeanPostProcessor的postProcessBeforeInitialization
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization
如果postProcessBeforeInitialization方法返回了一个对象,那么当前正在初始化的bean将被替换 当前正在初始化的bean是有属性值的
执行完BeanPostProcessor的初始化前置方法后,将执行 invokeInitMethods 方法,执行初始化方法
8.执行初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
首先判断是不是实现了 InitializingBean接口 如果实现了,将执行 afterPropertiesSet方法
判断有没有指定初始化方法,如果有,则通过反射执行指定的初始化方法
初始化方法执行完毕后回到initializeBean 方法,继续往下走,将执行执行BeanPostProcessor的后置方法
9. 初始化后执行BeanPostProcessor的postProcessAfterInitialization
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
BeanPostProcessor.postProcessAfterInitialization方法就牛逼了,代理类就在这里创建的,AOP基于此处实现的
在回到 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean,
从initializeBean(beanName, exposedObject, mbd)出来
继续往下走 如果出现了循环依赖
来到getSingleton(beanName, false)方法
注意一点 getSingleton(beanName, false); 调用 getSingleton方法传的参数时false,也就不会去三级缓存中拿
10.添加到单例缓冲池
bean已经实例化后,回到 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton 继续往下走
将调用afterSingletonCreation方法,将beanName从正在创建的beanName集合中删除
然后调用addSingleton(beanName, singletonObject);将当前bean添加到单例缓冲池中
`将创建好的单实例bean放入到单例缓存池中
this.singletonObjects.put(beanName, singletonObject);
`/ 从三级缓存中删除
this.singletonFactories.remove(beanName);
`从二级缓存中删除
this.earlySingletonObjects.remove(beanName);
`保存到已注册单实例Bean名称集合中
this.registeredSingletons.add(beanName);
至此 Spring中一个Bean的生命周期走完,流程比较多,下篇博文将详细画图,并解释三级缓存是如何解决循环依赖问题的
最后
以上就是腼腆小虾米为你收集整理的【Spring】Bean生命周期源码分析 下篇 属性填充以及初始化流程的全部内容,希望文章能够帮你解决【Spring】Bean生命周期源码分析 下篇 属性填充以及初始化流程所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复