Spring Bean生命周期介绍

音乐推荐

说明

  本篇主要介绍Spring Bean的生命周期以及Spring提供的对应各个生命周期的hook(钩子)介绍。

Spring 生命周期流程图

Spring依赖注入对象初始化阶段说明

  Spring支持属性注入、setter注入、构造器注入等依赖注入形式。这三种注入形式如下:

  1. 当注解@Autowired被标注在属性的setter方法上时执行setter注入,依赖对象在构造方法之后,setBeanName(String)方法之前直接注入到属性中(不通过setter方法);
  2. 当注解@Autowired被标注在属性声明上时执行属性注入,依赖对象在构造方法之后,setBeanName(String)方法之前通过setter方法完成注入;
  3. 当注解@Autowired被标注在构造器上,并且属性被定义为final类型时,执行构造器注入,依赖对象在调用构造方法时实现注入(Intellij IDEA推荐)。

  Spring4.3.2.RELEASE版本中支持以下这种特殊定义:

  类定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class LifeCycle implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
private final LifeDomain lifeDomain1;
private final LifeDomain lifeDomain2;
@Autowired
public LifeCycle(@Qualifier("lifeDomain2") LifeDomain lifeDomain2,
@Qualifier("lifeDomain1") LifeDomain lifeDomain1) {
yellow("LifeCircle -1- 构造方法");
validateProperties();
this.lifeDomain2 = lifeDomain2;
this.lifeDomain1 = lifeDomain1;
validateProperties();
}
}

  XML配置文件声明:

1
2
3
4
5
<bean
class="me.junbin.misc.candidate.spring.lifecycle.LifeCycle"
init-method="initMethod"
destroy-method="destroyMethod"
/>

  也就是说,Bean的定义可以不通过constructor-arg标签或者c命名空间来指定构造方法的参数。

Spring生命周期测试

  LifeCycle类:

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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package me.junbin.misc.candidate.spring.lifecycle;
import me.junbin.commons.ansi.ColorfulCustomizer;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import static me.junbin.commons.ansi.ColorfulPrinter.yellow;
/**
* @author : Zhong Junbin
* @email : <a href="mailto:junbinzhong@linkcm.com">发送邮件</a>
* @createDate : 2017/5/28 14:37
* @description :
* {@link org.springframework.beans.factory.support.ConstructorResolver#autowireConstructor(
*java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition,
* java.lang.reflect.Constructor[], java.lang.Object[])}
*/
public class LifeCycle implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
private final LifeDomain lifeDomain1;
private final LifeDomain lifeDomain2;
@Autowired
public LifeCycle(@Qualifier("lifeDomain2") LifeDomain lifeDomain2,
@Qualifier("lifeDomain1") LifeDomain lifeDomain1) {
yellow("LifeCircle -1- 构造方法");
validateProperties();
this.lifeDomain2 = lifeDomain2;
this.lifeDomain1 = lifeDomain1;
validateProperties();
}
@Override
public void setBeanName(String name) {
yellow("LifeCircle -2- setBeanName 方法");
validateProperties();
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
yellow("LifeCircle -3- setBeanFactory 方法");
validateProperties();
}
@PostConstruct
public void postConstruct() {
yellow("LifeCircle -4- @PostConstruct 方法");
validateProperties();
}
@Override
public void afterPropertiesSet() throws Exception {
yellow("LifeCircle -5- afterPropertiesSet 方法");
validateProperties();
}
public void initMethod() {
yellow("LifeCircle -6- init-method 方法");
validateProperties();
System.out.println("lifeDomain1 == lifeDomain2 ? ==> " + (lifeDomain1 == lifeDomain2));
}
@PreDestroy
public void preDestroy() {
yellow("LifeCircle -1- @PreDestroy 方法");
}
@Override
public void destroy() throws Exception {
yellow("LifeCircle -2- destroy 方法");
}
public void destroyMethod() {
yellow("LifeCircle -3- destroy-method 方法");
}
private void validateProperties() {
ColorfulCustomizer render = ColorfulCustomizer.start();
if (this.lifeDomain1 == null) {
render.fgRed().andThen(" lifeDomain1 --> null");
} else {
if (StringUtils.isNotEmpty(this.lifeDomain1.getMsg())) {
render.fgMagenta().andThen(" lifeDomain1 --> true");
} else {
render.fgRed().andThen(" lifeDomain1 --> false");
}
}
if (this.lifeDomain2 == null) {
render.fgBlue().andThen(", lifeDomain2 --> null");
} else {
if (StringUtils.isNotEmpty(this.lifeDomain2.getMsg())) {
render.fgCyan().andThen(", lifeDomain2 --> true");
} else {
render.fgBlue().andThen(", lifeDomain2 --> false");
}
}
render.output();
}
public LifeDomain getLifeDomain1() {
return lifeDomain1;
}
public LifeDomain getLifeDomain2() {
return lifeDomain2;
}
}

  XML配置文件中对该Bean的定义:

1
2
3
4
5
<bean
class="me.junbin.misc.candidate.spring.lifecycle.LifeCycle"
init-method="initMethod"
destroy-method="destroyMethod"
/>

  测试样例:

1
2
3
4
5
6
7
8
9
10
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:config/applicationContext.xml"})
public class TestLifeCircle {
@Test
public void testLifeCircle() throws Exception {
}
}

  测试结果:

Spring4生命周期.jpg

  如果需要在Bean实例化后结合属性执行某些操作时,建议通过实现InitializingBean接口来完成操作,同时,想要在SpringIoC容器关闭时执行某些清除操作,可以通过实现DisposableBean接口来实现。

编写日期:2017-06-03
发布日期:2017-06-03