重学spring(二) Spring中Bean的生命周期

Bean生命周期

上篇文章讲了Bean的四种实例化的四种方式。在传统应用这Bean的生命周期很简单,使用new关键字进行Bean的实例化,不再使用则由GC进行回收,相比之下,Spring管理Bean的生命周期则比较复杂。

如下图:

该图描述了singleton类型Bean的实例化过程

  1. Spring对Bean进行实例化;
  2. Spring将值和对Bean的引用注入进Bean对应的属性中;
  3. 如果Bean实现了BeanNameAware接口,Spring将Bean的ID传递给setBeanName()接口方法;
  4. 如果Bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()接口方法,将BeanFactory容器实例传入;
  5. 如果Bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()接口方法,将应用上下文的引用传入;
  6. 如果Bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessBeforeInitialization()接口方法;
  7. 如果Bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet()接口方法。类似的,如果Bean使用init-method声明了初始化方法,该方法也会被调用。
  8. 如果Bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessAfterInitialization()方法;
  9. 此时,Bean已经准备就绪,可以被使用了。它们将一直驻留在Spring容器中,直到容器被销毁;
  10. 如果Bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同样,如果Bean使用destroy-method声明了销毁方法,该方法也会被调用;

实验

  1. 定义User对象
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
package com.study.ioc.life_cycle;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class User implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {

private String name;

public User() {
}

public User(String name) {
System.out.println("constructor");
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
System.out.println("setName");
this.name = name;
}

public void setBeanName(String s) {
System.out.println("BeanNameAware#setBeanName");
}

public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("BeanFactoryAware#setBeanFactory");
}

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("ApplicationContextAware#setApplicationContext");
}

public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean#afterPropertiesSet");
}

public void initMethod() {
System.out.println("initMethod");
}

public void destroy() throws Exception {
System.out.println("destroy");
}

public void customerDestroyMethod() {
System.out.println("customerDestroyMethod");
}
}

  1. 定义TestBeanPostProcessor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.study.ioc.life_cycle;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class TestBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor#postProcessBeforeInitialization" + beanName);
return null;
}

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor#postProcessAfterInitialization" + beanName);
return null;
}
}

实现了BeanPostProcessor的类在每个Bean创建的时候都会调用,所以不能跟User放在一起。

  1. 定义xml
1
2
3
4
5
<bean id="testBeanPostProcessor" class="com.study.ioc.life_cycle.TestBeanPostProcessor"/>

<bean id="user" class="com.study.ioc.life_cycle.User" init-method="initMethod" destroy-method="customerDestroyMethod">
<property name="name" value="spring"/>
</bean>
  1. 测试
1
2
3
4
5
public static void main(String[] args) {
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) ctx.getBean("user");
ctx.close();
}
  1. 结果
1
2
3
4
5
6
7
8
9
10
setName
BeanNameAware#setBeanName
BeanFactoryAware#setBeanFactory
ApplicationContextAware#setApplicationContext
BeanPostProcessor#postProcessBeforeInitializationuser
InitializingBean#afterPropertiesSet
initMethod
BeanPostProcessor#postProcessAfterInitializationuser
destroy
customerDestroyMethod

从结果可以看到spring Bean的生命周期跟图中描述是一致的。有时我们会发现有实现BeanFactoryPostProcessor的类,那么 BeanFactoryPostProcessorBeanPostProcessor 有什么区别呢?

我们增加类TestBeanFactoryProcessor实现BeanFactoryPostProcessor

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.study.ioc.life_cycle;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class TestBeanFactoryProcessor implements BeanFactoryPostProcessor {

public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("BeanFactoryPostProcessor#postProcessBeanFactory");
}

}

增加Bean定义

1
<bean id="testBeanFactoryProcessor" class="com.study.ioc.life_cycle.TestBeanFactoryProcessor"/>

执行main方法,输出

1
2
3
4
5
6
7
8
9
10
11
BeanFactoryPostProcessor#postProcessBeanFactory
setName
BeanNameAware#setBeanName
BeanFactoryAware#setBeanFactory
ApplicationContextAware#setApplicationContext
BeanPostProcessor#postProcessBeforeInitializationuser
InitializingBean#afterPropertiesSet
initMethod
BeanPostProcessor#postProcessAfterInitializationuser
destroy
customerDestroyMethod

BeanFactoryPostProcessor最先执行。BeanFactoryPostProcessorBeanPostProcessor 的区别在于 BeanFactoryPostProcessor 在容器创建前执行,是对容器的增强。而BeanPostProcessor是对 Bean对象的增强,在每次创建Bean对象时都会执行


重学spring(二) Spring中Bean的生命周期
https://www.weypage.com/2020/05/13/Java框架/spring/IOC/bean的生命周期/
作者
weylan
发布于
2020年5月13日
许可协议