Spring Bean生命周期详解
文章目录Spring bean生命周期13个环节阶段1:Bean元信息配置阶段阶段2:Bean元信息解析阶段阶段3:Spring Bean注册阶段Spring bean生命周期13个环节阶段1:Bean元信息配置阶段阶段2:Bean元信息解析阶段阶段3:将Bean注册到容器中阶段4:BeanDefinition合并阶段阶段5:Bean Class加载阶段阶段6:Bean实例化阶段(...
文章目录
Spring bean生命周期13个环节
- 阶段1:Bean元信息配置阶段
- 阶段2:Bean元信息解析阶段
- 阶段3:将Bean注册到容器中
- 阶段4:BeanDefinition合并阶段
- 阶段5:Bean Class加载阶段
- 阶段6:Bean实例化阶段(2个小阶段)
- Bean实例化前阶段
- Bean实例化阶段
- 阶段7:合并后的BeanDefinition处理
- 阶段8:属性赋值阶段(3个小阶段)
- Bean实例化后阶段
- Bean属性赋值前阶段
- Bean属性赋值阶段
- 阶段9:Bean初始化阶段(5个小阶段)
- Bean Aware接口回调阶段
- Bean初始化前阶段
- Bean初始化阶段
- Bean初始化后阶段
- 阶段10:所有单例bean初始化完成后阶段
- 阶段11:Bean的使用阶段
- 阶段12:Bean销毁前阶段
- 阶段13:Bean销毁阶段
阶段1:Bean元信息配置阶段
这个阶段主要是bean信息的定义阶段
Bean信息定义4种方式
- API的方式
- Xml文件方式
- 注解的方式
- 类上标注@Compontent注解来定义一个bean
- 配置类中使用@Bean注解来定义bean
- 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元信息解析阶段
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);
if (result != null) {
return result;
}
}
}
return null;
}
上面代码中轮询beanPostProcessors列表,如果类型是InstantiationAwareBeanPostProcessor, 尝试调用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
获取bean的实例对象,如果能够获取到,那么将返回值作为当前bean的实例,那么spring自带的实例化bean的过程就被跳过了.
这个地方给开发者提供了一个扩展点,允许开发者在这个方法中直接返回bean的一个实例
见:com.dn.spring.beandefinition.BeanDefinition5Test#test1
Bean实例化操作
这个过程可以干什么?
这个过程会通过反射来调用bean的构造器来创建bean的实例。
org.springframework.beans.factory.config.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#applyMergedBeanDefinitionPostProcessors
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
在 postProcessMergedBeanDefinition 方法中对 @Autowired、@Value 标注的方法、字段进行缓存
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
在 postProcessMergedBeanDefinition 方法中对 @Resource 标注的字段、@Resource 标注的方法、 @PostConstruct 标注的字段、 @PreDestroy标注的方法进行缓存
阶段8:Bean属性设置阶段
实例化后阶段
会调用InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation这个方法
,调用逻辑如下:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
@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);
}
}
如果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方法设置的值。
见:com.dn.spring.beandefinition.BeanDefinition5Test#test4
阶段9:Bean初始化阶段
这个阶段分为5个小的阶段
- Bean Aware接口回调
- Bean初始化前操作
- Bean初始化操作
- Bean初始化后操作
- Bean初始化完成操作
Bean Aware接口回调
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
如果我们的bean实例实现了上面的接口,会按照下面的顺序依次进行调用,
BeanNameAware:将bean的名称注入进去
BeanClassLoaderAware:将BeanClassLoader注入进去
BeanFactoryAware:将BeanFactory注入进去
见:com.dn.spring.beandefinition.BeanDefinition5Test#test5
Bean初始化前操作
这个阶段的源码
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
会调用BeanPostProcessor的postProcessBeforeInitialization方法,若返回null,当前方法将结束。
通常称postProcessBeforeInitialization这个方法为:bean初始化前操作。
这个接口有2个实现类,比较重要:
org.springframework.context.support.ApplicationContextAwareProcessor
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
ApplicationContextAwareProcessor注入6个Aware接口对象
如果bean实现了下面的接口,在ApplicationContextAwareProcessor#postProcessBeforeInitialization中会依次调用下面接口中的方法,将Aware前缀对应的对象注入到bean实例中。
EnvironmentAware:注入Environment对象 EmbeddedValueResolverAware:注入EmbeddedValueResolver对象 ResourceLoaderAware:注入ResourceLoader对象 ApplicationEventPublisherAware:注入ApplicationEventPublisher对象 MessageSourceAware:注入MessageSource对象 ApplicationContextAware:注入ApplicationContext对象
CommonAnnotationBeanPostProcessor调用@PostConstruct标注的方法
CommonAnnotationBeanPostProcessor#postProcessBeforeInitialization中会调用bean中所有标注@PostConstruct注解的方法
ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
if (initAnnotationType != null) {
if (method.getAnnotation(initAnnotationType) != null) {
LifecycleElement element = new LifecycleElement(method);
currInitMethods.add(element);
if (debug) {
logger.debug("Found init method on class [" + clazz.getName() + "]: " + method);
}
}
}
if (destroyAnnotationType != null) {
if (method.getAnnotation(destroyAnnotationType) != null) {
currDestroyMethods.add(new LifecycleElement(method));
if (debug) {
logger.debug("Found destroy method on class [" + clazz.getName() + "]: " + method);
}
}
}
}
})
调用@PostConstruct标注的方法
见:com.dn.spring.beandefinition.BeanDefinition5Test#test6
Bean初始化阶段
2个步骤
- 调用InitializingBean接口的afterPropertiesSet方法
- 调用定义bean的时候指定的初始化方法。
见:com.dn.spring.beandefinition.BeanDefinition5Test#test7
Bean初始化后阶段
这块的源码:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
@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;
}
调用BeanPostProcessor接口的postProcessAfterInitialization方法,返回null的时候,会中断上面的操作。
通常称 postProcessAfterInitialization 这个方法为:bean初始化后置操作。
见:com.dn.spring.beandefinition.BeanDefinition5Test#test8
阶段10:所有单例bean初始化完成后阶段
所有单例bean实例化完成之后,spring会回调下面这个接口:
public interface SmartInitializingSingleton {
void afterSingletonsInstantiated();
}
调用逻辑在下面这个方法中
//确保所有非lazy的单例都被实例化,同时考虑到FactoryBeans。 //如果需要,通常在工厂设置结束时调用。 org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
这个方法内部会先触发所有非延迟加载的单例bean初始化,然后从容器中找到类型是SmartInitializingSingleton的bean,调用他们的afterSingletonsInstantiated方法。
见:com.dn.spring.beandefinition.BeanDefinition6Test
阶段11:Bean使用阶段
调用getBean方法得到了bean之后
阶段12:Bean销毁阶段
触发bean销毁的几种方式
调用org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#destroyBean
调用org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons
调用ApplicationContext中的close方法
Bean销毁阶段会依次执行
- 轮询beanPostProcessors列表,如果是DestructionAwareBeanPostProcessor这种类型的,会调用其内部的postProcessBeforeDestruction方法
- 如果bean实现了org.springframework.beans.factory.DisposableBean接口,会调用这个接口中的destroy方法
- 调用bean自定义的销毁方法
DestructionAwareBeanPostProcessor接口
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
/**
* bean销毁前调用的方法
*/
void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
/**
* 用来判断bean是否需要触发postProcessBeforeDestruction方法
*/
default boolean requiresDestruction(Object bean) {
return true;
}
}
这个接口有个关键的实现类:
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor#postProcessBeforeDestruction方法中会调用bean中所有标注了@PreDestroy的方法。
源码在
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#postProcessBeforeDestruction
见:com.dn.spring.beandefinition.BeanDefinition7Test
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor 用来处理@Resource、@PostConstruct、@PreDestroy的
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor 用来处理@Autowired、@Value注解
org.springframework.context.support.ApplicationContextAwareProcessor 用来回调Bean实现的各种Aware接口
AbstractApplicationContext类
-
BeanFactory接口
Bean工厂的顶层接口 -
DefaultListableBeanFactory类
实现了BeanFactory接口,可以说这个可以是BeanFactory接口真正的唯一实现,内部真正实现了bean生命周期中的所有代码。其他的一些类都是依赖于DefaultListableBeanFactory类,将请求转发给DefaultListableBeanFactory进行bean的处理的。
-
其他
我们经常用到的就是这3个类:
AnnotationConfigApplicationContext ClassPathXmlApplicationContext FileSystemXmlApplicationContext这3个类
,
他们的主要内部的功能是依赖他的父类AbstractApplicationContext来实现的,所以大家主要看AbstractApplicationContext这个类。
AbstractApplicationContext类
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory)
第一个方法:getBeanFactory()
返回当前应用上下文中的ConfigurableListableBeanFactory,这也是个接口类型的,这个接口有一个唯一的实现类:DefaultListableBeanFactory。
上面说过:DefaultListableBeanFactory是BeanFactory真正的唯一实现。
应用上下文中就会使用这个ConfigurableListableBeanFactory来操作spring容器。
第二个方法:registerBeanPostProcessors
这个方法就是向ConfigurableListableBeanFactory中注册BeanPostProcessor
,内部会从spring容器中获取所有类型的BeanPostProcessor,将其添加到DefaultListableBeanFactory#beanPostProcessors列表中
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
会将请求转发给PostProcessorRegistrationDelegate#registerBeanPostProcessors
这个方法内部主要用到了4个BeanPostProcessor类型的List集合。
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> orderedPostProcessors
List<BeanPostProcessor> nonOrderedPostProcessors;
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
spring会从容器中找出所有类型的BeanPostProcessor列表,然后按照下面的规则将其分别放到上面的4个集合中
,上面4个集合中的BeanPostProcessor会被依次添加到DefaultListableBeanFactory#beanPostProcessors列表中,来看一下4个集合的分别放的是那些BeanPostProcessor:
priorityOrderedPostProcessors(指定优先级的BeanPostProcessor)
实现org.springframework.core.PriorityOrdered接口的BeanPostProcessor,但是不包含MergedBeanDefinitionPostProcessor类型的
orderedPostProcessors(指定了顺序的BeanPostProcessor)
标注有@Order注解,或者实现了org.springframework.core.annotation.Order接口的BeanPostProcessor,但是不包含MergedBeanDefinitionPostProcessor类型的
nonOrderedPostProcessors(未指定顺序的BeanPostProcessor)
上面2中类型之外以及MergedBeanDefinitionPostProcessor之外的
internalPostProcessors
MergedBeanDefinitionPostProcessor类型的BeanPostProcessor列表。
看一下CommonAnnotationBeanPostProcessor和AutowiredAnnotationBeanPostProcessor,这两个类都实现了PriorityOrdered接口,但是他们也实现了MergedBeanDefinitionPostProcessor接口,所以最终他们会被丢到internalPostProcessors这个集合中,会被放入BeanPostProcessor的最后面
Bean生命周期流程图
参考
更多推荐
所有评论(0)