Bean的生命周期
- Bean的生命周期图示如下:
- 文字描述如下:
- Spring启动,查找并加载需要被Spring管理的bean,进行Bean的实例化。
- Bean实例化后对将Bean的引入和值注入到Bean的属性中。
- 如果Bean实现了BeanNameAware接口,Spring将Bean的Id传递给setBeanName()方法。
- 如果Bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入。
- 如果Bean实现了ApplicationContextAware接口,Spring将调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入进来。
- 如果Bean实现了BeanPostProcessor接口,Spring就将调用他们的postProcessBeforeInitialization()方法。
- 如果Bean使用了@PostConstruct注解进行初始化,则会调用该注解标注的方法;如果Bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet()方法;如果bean使用init-method声明了初始化方法,该方法也会被调用。
- 如果Bean 实现了BeanPostProcessor接口,Spring就将调用他们的postProcessAfterInitialization()方法。
- 此时,Bean已经准备就绪,可以被应用程序使用了。他们将一直驻留在应用上下文中,直到应用上下文被销毁。
- 如果Bean使用了@PreDestroy注解进行销毁,则会调用此注解标注的销毁方法;如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法;如果bean使用了destory-method 声明销毁方法,该方法也会被调用。
参考:https://www.cnblogs.com/javazhiyin/p/10905294.html
- 测试Bean的生命周期:
1 | public class MyBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean { |
测试结果:
1 | ------提示:现在开始初始化容器------ |
其中,指定初始化和销毁方法的几种方式:
- ①通过@Bean指定init-method和destroy-method。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35public class Car {
public Car(){
System.out.println("car constructor...");
}
public void init(){
System.out.println("car ... init...");
}
public void destroy(){
System.out.println("car ... destroy...");
}
}
public class MainConfig {
public Car car() {
return new Car();
}
}
public class MainTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("容器初始化完成");
//关闭容器
applicationContext.close();
//打印如下:
//car constructor...
//car ... init...
//容器初始化完成
//car ... destroy...
}
}- ②通过让Bean实现InitializingBean(定义初始化逻辑),DisposableBean(定义销毁逻辑)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35public class Car implements InitializingBean, DisposableBean {
public Car(){
System.out.println("car constructor...");
}
public void destroy() throws Exception {
System.out.println("car...destroy...");
}
public void afterPropertiesSet() throws Exception {
System.out.println("car...afterPropertiesSet...");
}
}
public class MainConfig {
public Car car() {
return new Car();
}
}
public class MainTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("容器初始化完成");
//关闭容器
applicationContext.close();
//打印如下:
//car constructor...
//car...afterPropertiesSet...
//容器初始化完成
//car...destroy...
}
}- ③使用@PostConstruct: 在bean创建完成并且属性赋值完成后来执行初始化方法;@PreDestroy: 在容器销毁bean之前通知我们进行清理工作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39public class Car {
public Car(){
System.out.println("car constructor...");
}
//对象创建并赋值之后调用
public void init(){
System.out.println("car....@PostConstruct...");
}
//容器移除对象之前
public void destroy(){
System.out.println("car....@PreDestroy...");
}
}
public class MainConfig {
public Car car() {
return new Car();
}
}
public class MainTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("容器初始化完成");
//关闭容器
applicationContext.close();
//打印如下:
//car constructor...
//car....@PostConstruct...
//容器初始化完成
//car....@PreDestroy...
}
}Spring底层几个后置处理器的作用:
- ApplicationContextAwareProcessor是BeanPostProcessor(后置处理器)的一个实现类,其作用是如果bean对象的类是ApplicationContextAware类型,则会执行setApplicationContext方法将IOC容器赋值给此bean对象。上述例子的MyBean即实现了ApplicationContextAware接口从而得到IOC容器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
private final StringValueResolver embeddedValueResolver;
/**
* Create a new ApplicationContextAwareProcessor for the given context.
*/
public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
return bean;
}
AccessControlContext acc = null;
if (System.getSecurityManager() != null) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
//给bean赋值IOC容器
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}- InitDestroyAnnotationBeanPostProcessor 也是 BeanPostProcessors 的一个实现类,其对 BeanPostProcessor 的实现是通过同时实现 DestructionAwareBeanPostProcessor 和 MergedBeanDefinitionPostProcessor 这两个接口来完成的,其允许使用注解替代 Spring 的 InitializingBean 和 DisposableBean 回调接口,上述的第③种初始化方法的**@PostConstruct** 和 @PreDestroy 注解发挥作用就是由其实现的。核心源码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 调用方法获取生命周期元数据并保存
LifecycleMetadata metadata = findLifecycleMetadata(beanType);
// 验证相关方法
metadata.checkConfigMembers(beanDefinition);
}
private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
if (this.lifecycleMetadataCache == null) {
// 在 Bean 销毁过程中反序列化后调用
// Happens after deserialization, during destruction...
return buildLifecycleMetadata(clazz);
}
// Quick check on the concurrent map first, with minimal locking.
// 首先尝试从缓存中获取元数据
LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);
//如果从缓存中获取失败则尝试加锁创建元数据
if (metadata == null) {
synchronized (this.lifecycleMetadataCache) {
metadata = this.lifecycleMetadataCache.get(clazz);
if (metadata == null) {
//构建生命周期元数据,也就是解析带 @PostConstruct 和 @PreDestroy 注解的方法。
metadata = buildLifecycleMetadata(clazz);
this.lifecycleMetadataCache.put(clazz, metadata);
}
return metadata;
}
}
return metadata;
}
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
return this.emptyLifecycleMetadata;
}
// 实例化后的回调方法(@PostConstruct)
List<LifecycleElement> initMethods = new ArrayList<>();
// 销毁前的回调方法(@PreDestroy)
List<LifecycleElement> destroyMethods = new ArrayList<>();
// 获取正在处理的目标类
Class<?> targetClass = clazz;
do {
// 下面两个列表是为了保存每一轮循环搜索到的相关方法(因为可能存在父类)
final List<LifecycleElement> currInitMethods = new ArrayList<>();
final List<LifecycleElement> currDestroyMethods = new ArrayList<>();
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
// 当前方法的注解中包含 initAnnotationType 注解时(此时就是 @PostConstruct)
if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
LifecycleElement element = new LifecycleElement(method);
currInitMethods.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
}
}
// 当前方法的注解中包含 destroyAnnotationType 注解时(此时就是 @PreDestroy)
if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
// 创建一个元数据元素(当前方法的包装类)并添加到集合中
currDestroyMethods.add(new LifecycleElement(method));
if (logger.isTraceEnabled()) {
logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);
}
}
});
//将本次循环中获取到的对应方法集合(currInitMethods 和 currDestroyMethods)保存到总集合(initMethods 和 destroyMethods)中
initMethods.addAll(0, currInitMethods);
destroyMethods.addAll(currDestroyMethods);
// 获取当前类的父类
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
new LifecycleMetadata(clazz, initMethods, destroyMethods));
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 尝试从缓存中获取元数据
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
// 通过元数据 LifecycleMetadata 中的 invokeInitMethods 方法调用初始化方法(@PostConstruct)
metadata.invokeInitMethods(bean, beanName);
}
catch (InvocationTargetException ex) {
throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
}
return bean;
}而销毁前调用**@PreDestroy**标注的方法的实现在DisposableBeanAdapter的destroy()方法中:
1
2
3
4
5
6
7
8
9public void destroy() {
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
// 当这里的processor为CommonAnnotationBeanPostProcessor 时调用 @PreDestroy方法,因为CommonAnnotationBeanPostProcessor中未实现postProcessBeforeDestruction方法,因此直接调用其父类 InitDestroyAnnotationBeanPostProcessor 中的 postProcessBeforeDestruction 方法
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
...
}