Spring Bean生命周期详解

Spring bean生命周期13个环节

  1. 阶段1:Bean元信息配置阶段
  2. 阶段2:Bean元信息解析阶段
  3. 阶段3:将Bean注册到容器中
  4. 阶段4:BeanDefinition合并阶段
  5. 阶段5:Bean Class加载阶段
  6. 阶段6:Bean实例化阶段(2个小阶段)
    • Bean实例化前阶段
    • Bean实例化阶段
  7. 阶段7:合并后的BeanDefinition处理
  8. 阶段8:属性赋值阶段(3个小阶段)
    • Bean实例化后阶段
    • Bean属性赋值前阶段
    • Bean属性赋值阶段
  9. 阶段9:Bean初始化阶段(5个小阶段)
    • Bean Aware接口回调阶段
    • Bean初始化前阶段
    • Bean初始化阶段
    • Bean初始化后阶段
  10. 阶段10:所有单例bean初始化完成后阶段
  11. 阶段11:Bean的使用阶段
  12. 阶段12:Bean销毁前阶段
  13. 阶段13:Bean销毁阶段

阶段1:Bean元信息配置阶段

这个阶段主要是bean信息的定义阶段
Bean信息定义4种方式

  1. API的方式
  2. Xml文件方式
  3. 注解的方式
    • 类上标注@Compontent注解来定义一个bean
    • 配置类中使用@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元信息解析阶段

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销毁的几种方式

  1. 调用org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#destroyBean
  2. 调用org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons
  3. 调用ApplicationContext中的close方法

Bean销毁阶段会依次执行

  1. 轮询beanPostProcessors列表,如果是DestructionAwareBeanPostProcessor这种类型的,会调用其内部的postProcessBeforeDestruction方法
  2. 如果bean实现了org.springframework.beans.factory.DisposableBean接口,会调用这个接口中的destroy方法
  3. 调用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

  1. org.springframework.context.annotation.CommonAnnotationBeanPostProcessor 用来处理@Resource、@PostConstruct、@PreDestroy的
  2. org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor 用来处理@Autowired、@Value注解
  3. 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生命周期流程图

在这里插入图片描述

参考

spring 5.2.3 官网地址
Spring Bean生命周期详解

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值