10 深入理解spring生命周期与BeanPostProcessor的实现原理
新建一个User1对象如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23/**
* 定义一个实现InitializingBean DisposableBean的bean
*
* @author
* @date 2018年5月4日
*/
public class User1 implements InitializingBean,DisposableBean{
public User1(){
System.out.println("实例化User1的构造方法......");
}
public void destroy() throws Exception {
System.out.println("调用实现DisposableBean的destroy方法....");
}
public void afterPropertiesSet() throws Exception {
System.out.println("调用实现InitializingBean的afterPropertiesSet方法......");
}
public void initUser(){
System.out.println("执行initMethod方法.....");
}
public void destroyUser(){
System.out.println("执行destroyMethod方法......");
}
}
新建一个MyBeanPostProcessor实现BeanPostProcessor如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20/**
* 定义一个前置后置处理器
*
* @author
* @date 2018年5月6日
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
// 这边只做简单打印 原样返回bean
System.out.println("postProcessBeforeInitialization===="+beanName);
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
// 这边只做简单打印 原样返回bean
System.out.println("postProcessAfterInitialization===="+beanName);
return bean;
}
}
主配置文件如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/**
* 定义一个注解配置文件 必须要加上@Configuration注解
*
* @author
* @date 2018年4月30日
*/
public class MainConfig {
"initUser",destroyMethod="destroyUser") (initMethod=
public User1 getUser1(){
return new User1();
}
public MyBeanPostProcessor getMyBeanPostProcessor(){
return new MyBeanPostProcessor();
}
}
测试代码如下:1
2
3
4
5public static void main(String[] args) {
// 使用AnnotationConfigApplicationContext获取spring容器ApplicationContext2
AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(MainConfig.class);
applicationContext2.close();
}
运行结果如下:
1 | 实例化User1的构造方法...... |
从结果中可以看出他们之前执行的顺序如下:注意其中的位置序号下边文章会用到
- 1,首先执行bean的构造方法,
- 2,BeanPostProcessor的postProcessBeforeInitialization方法
- 3,InitializingBean的afterPropertiesSet方法
- 4,@Bean注解的initMethod方法
- 5,BeanPostProcessor的postProcessAfterInitialization方法
- 6,DisposableBean的destroy方法
- 7,@Bean注解的destroyMethod方法
接下来我们再来看看spring底层的实现,首先进入程序的启动类AnnotationConfigApplicationContext方法如下:1
2
3
4
5public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
里边有两个方法一个是register注册对应的java配置类和另一个是refresh方法,我们重点来看这个refresh方法如下:
1 |
|
接下来我们重点来看下finishBeanFactoryInitialization
实例化bean的方法,进去之后我们发现最后有一个preInstantiateSingletons
方法如下:
1 | protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { |
继续查看preInstantiateSingletons
对应实现如下:
1 |
|
我们发现里边的关键方法getBean如下:1
2
3
4
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
继续跟进去如下:
1 | protected <T> T doGetBean( |
接下来重点看一下其中创建bean的方法createBean如下:1
2
3
4
5
6
7
8
9
10protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// 省略部分代码
// 重点注意doCreateBean方法
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
继续跟进可以看到doCreateBean方法如下: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
33protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// 省略部分代码
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 设置bean 属性
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
// 省略部分代码......
// Register bean as disposable.
// 注意这个地方 下面讲销毁的时候说讲到
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
可以发现其中有一个initializeBean方法如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
// 省略部分代码。。。。
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 重点来了BeanPostProcessor的postProcessBeforeInitialization方法执行的地方
// 这也是为什么他执行所有的初始化之前的原因了 位置2
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 初始化bean
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor的PostProcessorsAfterInitialization方法执行的地方
// 初始化完成之后执行BeanPostProcessor的postProcessorsAfterInitialization 位置5
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
到这BeanPostProcessor的实现已经很清晰了吧,BeanPostProcessor
的postProcessBeforeInitialization
(方法位置2)和BeanPostProcessor
的postProcessAfterInitialization
(方法位置5)的执行位置我们搞清楚了,那上面的位置3和位置4又是怎么执行的呢,让我们继续到invokeInitMethods里边看看如下:
1 | protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) |
聪明的你应该一眼就能看到位置3,以及位置4的执行顺序了吧
好了初始化的逻辑部分搞清楚了,接下来我们一起来看看销毁的流程,销毁开始于applicationContext.close();方法,点进去看如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void close() {
synchronized (this.startupShutdownMonitor) {
doClose();
// If we registered a JVM shutdown hook, we don't need it anymore now:
// We've already explicitly closed the context.
if (this.shutdownHook != null) {
try {
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
}
catch (IllegalStateException ex) {
// ignore - VM is already shutting down
}
}
}
}
看到其中有一个doClose继续跟进去看会发现有一个destroyBeans方法,再进去直到找到destroySingletons方法如下:1
2
3
4
5
6
7
8public void destroySingletons() {
// 省略部分代码
// 循环所有的disposableBean执行对应的destroy方法
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
}
// 省略部分代码
}
在继续从destroySingleton方法进去可以找到destroyBean方法如下:1
2
3
4
5
6
7
8
9
10
11
12
13protected void destroyBean(String beanName, DisposableBean bean) {
// 省略部分代码
// 重点的地方到了 执行DisposableBean 中的destroy 也就是位置6 中对应的打印
if (bean != null) {
try {
bean.destroy();
}
catch (Throwable ex) {
logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
}
}
// 省略部分代码
}
到这里我们已经完成了90%的原理分析了,这个时候细心的你一定会发现那位置7中的@Bean注解中配置的destroyMethod是在什么时候调用的呢,好像上面都没有讲到,要想知道destroyMethod的调用让我们回到上面讲bean初始化中的doCreateBean方法中其中有一个registerDisposableBeanIfNecessary方法进去看如下:
1 | protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { |
继续进去到DisposableBeanAdapter类如下: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
34public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
List<BeanPostProcessor> postProcessors, AccessControlContext acc) {
Assert.notNull(bean, "Disposable bean must not be null");
this.bean = bean;
this.beanName = beanName;
this.invokeDisposableBean =
(this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
this.acc = acc;
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
this.destroyMethodName = destroyMethodName;
this.destroyMethod = determineDestroyMethod();
if (this.destroyMethod == null) {
if (beanDefinition.isEnforceDestroyMethod()) {
throw new BeanDefinitionValidationException("Couldn't find a destroy method named '" +
destroyMethodName + "' on bean with name '" + beanName + "'");
}
}
else {
Class<?>[] paramTypes = this.destroyMethod.getParameterTypes();
if (paramTypes.length > 1) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has more than one parameter - not supported as destroy method");
}
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has a non-boolean parameter - not supported as destroy method");
}
}
}
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
}
怎么样,到现在是不是就很清晰了,位置7的打印其实也是DisposableBean方法中打印出来的,@bean注解的destroyMethod其实是在初始化的时候转换成DisposableBean的实现放入到了disposableBeans中
Spring中Bean的生命周期流程图如下
总结:查看BeanPostProcessor
的子类,发现spring大部分功能都是通过BeanPostProcessor
来实现,比如,属性注入,*Aware组件,@Autowired注解,生命周期注解(PostConstruct,PreDestroy)等功能都是通过BeanPostProcessor
完成
- BeanPostProcessor子类
- 1.AutowiredAnnotationBeanPostProcessor:完成@Autowired注入
- 2.ApplicationContextAwareProcessor: 完成Aware接口注入
- 3.AsyncAnnotationBeanPostProcessor: 完成@Async 异步功能
- …..
本文大部分转自:51CTO博客-知了123