SpringBean⽣命周期详解
⽂章⽬录
Spring bean⽣命周期13个环节
1. 阶段1:Bean元信息配置阶段
2. 阶段2:Bean元信息解析阶段
3. 阶段3:将Bean注册到容器中
4. 阶段4:BeanDefinition合并阶段
5. 阶段5:Bean Class加载阶段
6. 阶段6:Bean实例化阶段(2个⼩阶段)
1. Bean实例化前阶段
2. Bean实例化阶段
7. 阶段7:合并后的BeanDefinition处理
8. 阶段8:属性赋值阶段(3个⼩阶段)
1. Bean实例化后阶段
2. Bean属性赋值前阶段
3. Bean属性赋值阶段
9. 阶段9:Bean初始化阶段(5个⼩阶段)
1. Bean Aware接⼝回调阶段
2. Bean初始化前阶段
3. Bean初始化阶段
4. Bean初始化后阶段
10. 阶段10:所有单例bean初始化完成后阶段
11. 阶段11:Bean的使⽤阶段
12. 阶段12:Bean销毁前阶段
13. 阶段13:Bean销毁阶段
阶段1:Bean元信息配置阶段
这个阶段主要是bean信息的定义阶段
Bean信息定义4种⽅式
1. API的⽅式
2. Xml⽂件⽅式
3. 注解的⽅式
1. 类上标注@Compontent注解来定义⼀个bean
2. 配置类中使⽤@Bean注解来定义bean
4. properties⽂件的⽅式
Spring容器启动的过程中,会将Bean解析成Spring内部的BeanDefinition结构。
不管是是通过xml配置⽂件的标签,还是通过注解配置的@Bean,还是@Compontent标注的类,还是扫描得到的类,它最终都会被解析成⼀个BeanDefinition对象,最后我们的Bean⼯⼚就会根据这份Bean的定义信息,对bean进⾏实例化、初始化等等操作。
你可以把BeanDefinition丢给Bean⼯⼚,然后Bean⼯⼚就会根据这个信息帮你⽣产⼀个Bean实例
BeanDefinition接⼝:bean定义信息接⼝
AttributeAccessor接⼝:属性访问接⼝
BeanMetadataElement接⼝:返回BeanDefinition定义的来源
RootBeanDefinition类:表⽰根bean定义信息
ChildBeanDefinition类:表⽰⼦bean定义信息
GenericBeanDefinition类:通⽤的bean定义信息
ConfigurationClassBeanDefinition类:表⽰通过配置类中@Bean⽅法定义bean信息
AnnotatedBeanDefinition接⼝:表⽰通过注解的⽅式定义的bean信息
BeanDefinitionBuilder:构建BeanDefinition的⼯具类,可以⾮常⽅便的组装BeanDefinition对象
见:com.dn.spring.beandefinition.BeanDefinition1Test
阶段2:Bean元信息解析阶段
c语言编程判断是否为闰年Bean元信息的解析主要有3种⽅式
xml⽂件定义bean的解析
XML⽅式解析:XmlBeanDefinitionReader
properties⽂件定义bean的解析
properties⽂件定义bean的解析:PropertiesBeanDefinitionReader
注解⽅式定义bean的解析
AnnotatedBeanDefinitionReader
见:com.dn.spring.beandefinition.BeanDefinition2Test
阶段3:Spring Bean注册阶段
bean注册阶段需要⽤到⼀个⾮常重要的接⼝:BeanDefinitionRegistry
别名注册接⼝:AliasRegistry
BeanDefinitionRegistry接⼝继承了AliasRegistry接⼝,这个接⼝中定义了操作bean别名的⼀些⽅法。
BeanDefinitionRegistry唯⼀实现:DefaultListableBeanFactory
org.springframework.beans.factory.support.DefaultListableBeanFactory
例如 AnnotationConfigApplicationContext 类就实现了 BeanDefinitionRegistry接⼝
从阶段4到阶段14,也就是从:BeanDefinition合并阶段到Bean初始化完成阶段,都是在调⽤getBean从容器中获取bean对象的过程中发送的操作.
getBean这个⽅法的源码
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
见:com.dn.spring.beandefinition.BeanDefinition3Test
阶段4:BeanDefinition合并阶段
阶段4:BeanDefinition合并阶段
org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefinition
bean定义可能存在多级⽗⼦关系,合并的时候进进⾏递归合并,最终得到⼀个包含完整信息的RootBeanDefinition.
合并之前是GenericBeanDefinition类型的,合并之后得到的是RootBeanDefinition类型的。
后⾯的阶段将使⽤合并产⽣的RootBeanDefinition
见:com.dn.spring.beandefinition.BeanDefinition4Test
阶段5:Bean Class加载阶段
这个阶段就是将bean的class名称转换为Class类型的对象。
此时会对阶段4中合并产⽣的RootBeanDefinition中的beanClass进⾏解析,将bean的类名转换为Class对象,然后赋值给RootBeanDefinition#setBeanClassName字段
源码位置:
org.springframework.beans.factory.support.AbstractBeanFactory#resolveBeanClass
上⾯得到了Bean Class对象以及合并之后的BeanDefinition,下⾯就开始进⼊实例化这个对象的阶段了。
Bean实例化分为3个阶段:前阶段、实例化阶段、后阶段;
阶段6:Bean实例化阶段
Bean实例化前操作
看⼀下 DefaultListableBeanFactory
在 ⽗类 AbstractBeanFactory 中
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
是⼀个BeanPostProcessor类型的集合
spring在bean⽣命周期的不同阶段,会调⽤上⾯这个列表中的BeanPostProcessor中的⼀些⽅法,来对⽣命周期进⾏扩展,bean⽣命周期中的所有扩展点都是依靠这个集合中的BeanPostProcessor来实现的
Bean实例化之前会调⽤⼀段代码:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName){
for(BeanPostProcessor bp :getBeanPostProcessors()){
if(bp instanceof InstantiationAwareBeanPostProcessor){
InstantiationAwareBeanPostProcessor ibp =(InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
this的对应词和复数if(result != null){
return result;
}
}
}
return null;
}
上⾯代码中轮询beanPostProcessors列表,如果类型是InstantiationAwareBeanPostProcessor, 尝试调
⽤InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation获取bean的实例对象,如果能够获取到,那么将返回值作为当前bean的实例,那么spring⾃带的实例化bean的过程就被跳过了.
这个地⽅给开发者提供了⼀个扩展点,允许开发者在这个⽅法中直接返回bean的⼀个实例flex start
见:com.dn.spring.beandefinition.BeanDefinition5Test#test1
这个过程可以⼲什么?
这个过程会通过反射来调⽤bean的构造器来创建bean的实例。
org.springframework.fig.SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
这个⽅法会返回候选的构造器列表,也可以返回空.
protected Constructor<?>[]determineConstructorsFromBeanPostProcessors(Class<?> beanClass, String beanName)
throws BeansException {
if(beanClass != null &&hasInstantiationAwareBeanPostProcessors()){
for(BeanPostProcessor bp :getBeanPostProcessors()){
if(bp instanceof SmartInstantiationAwareBeanPostProcessor){
SmartInstantiationAwareBeanPostProcessor ibp =(SmartInstantiationAwareBeanPostProcessor) bp;
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if(ctors != null){
return ctors;
}
}
}
}
return null;
}
具体需要使⽤哪个构造器,spring为开发者提供了⼀个接⼝,允许开发者⾃⼰来判断⽤哪个构造器。
重要的实现类 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
可以将@Autowired标注的⽅法作为候选构造器返回
见:com.dn.spring.beandefinition.BeanDefinition5Test#test2
到⽬前为⽌bean实例化阶段结束了
阶段7:合并后的BeanDefinition处理
这块的源码如下
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcess ors
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName){
for(BeanPostProcessor bp :getBeanPostProcessors()){
if(bp instanceof MergedBeanDefinitionPostProcessor){
MergedBeanDefinitionPostProcessor bdp =(MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
会调⽤MergedBeanDefinitionPostProcessor接⼝的postProcessMergedBeanDefinition⽅法
第⼀个参数为beanDefinition,表⽰合并之后的RootBeanDefinition,我们可以在这个⽅法内部对合并之后的BeanDefinition进⾏再次处理
实现类
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
vbse实训心得体会出纳在 postProcessMergedBeanDefinition ⽅法中对 @Autowired、@Value 标注的⽅法、字段进⾏缓存
t.annotation.CommonAnnotationBeanPostProcessor
在 postProcessMergedBeanDefinition ⽅法中对 @Resource 标注的字段、@Resource 标注的⽅法、 @PostConstruct 标注的字段、 @PreDestroy标注的⽅法进⾏缓存
阶段8:Bean属性设置阶段
会调⽤InstantiationAwareBeanPostProcessor接⼝的postProcessAfterInstantiation这个⽅法,调⽤逻辑如下:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitializati on
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for(BeanPostProcessor beanProcessor :getBeanPostProcessors()){
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if(result == null){
return result;
}
}
return result;
}
postProcessAfterInstantiation⽅法返回false的时候,后续的Bean属性赋值前处理、Bean属性赋值都会被跳过
Bean属性赋值前阶段
这个阶段会调⽤InstantiationAwareBeanPostProcessor接⼝的postProcessPropertyValues⽅法,调⽤逻辑
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
if(hasInstAwareBpps || needsDepCheck){
PropertyDescriptor[] filteredPds =filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if(hasInstAwareBpps){
for(BeanPostProcessor bp :getBeanPostProcessors()){
if(bp instanceof InstantiationAwareBeanPostProcessor){
InstantiationAwareBeanPostProcessor ibp =(InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if(pvs == null){
return;
}
}
}
}
if(needsDepCheck){
checkDependencies(beanName, mbd, filteredPds, pvs);
properties是什么文件
}
}
编程工具栏图标下载免费如果InstantiationAwareBeanPostProcessor中的postProcessPropertyValues返回空的时候,表⽰这个bean不需要设置属性,直接返回了,直接进⼊下⼀个阶段
PropertyValues 保存了bean实例对象中所有属性值的设置,所以我们可以在postProcessPropertyValues 这个⽅法中对PropertyValues值进⾏修改。
见:com.dn.spring.beandefinition.BeanDefinition5Test#test3
这个⽅法有2个⽐较重要的实现类
AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues在这个⽅法中对@Autowired、@Value标注的字段、⽅法注⼊值。
CommonAnnotationBeanPostProcessor#postProcessPropertyValues在这个⽅法中对@Resource标注的字段和⽅法注⼊值。
Bean属性赋值阶段
这个过程⽐较简单了,循环处理PropertyValues中的属性值信息,通过反射调⽤set⽅法将属性的值设置到bean实例中。
PropertyValues中的值是通过bean xml中property元素配置的,或者调⽤MutablePropertyValues中add⽅法设置的值。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论