Spring注解驱动开发(二)-Bean的生命周期

Bean的生命周期:
bean创建—初始化—-销毁的过程

容器管理bean的生命周期;
我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。

1. 指定初始化和销毁方法

1.1 xml方式

1
2
<bean id="person" class="com.rocklei123.bean.Person" init-method="" destroy-method="">
</bean>

1.2 注解方式

可通过@Bean(initMethod = “init”,destroyMethod = “destroy”)指定初始化及销毁方法,通过测试可以确定:

构造对象

  • 单实例:在容器启动的时候创建对象
  • 多实例:在每次获取的时候创建对象

初始化

* 对象创建完成,并赋值好,调用初始化方法。

销毁:

  • 单实例:容器关闭的时候
  • 多实例:容器不会管理这个bean;容器不会调用销毁方法;

1.2.1 单实例情况测试

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
public 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...");
}
}
@Configuration
public class MainConfigLifeCycle {
@Bean(initMethod = "init",destroyMethod = "destroy")
public Car car() {
return new Car();
}
}
@Test
public void testLifeCycle() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigLifeCycle.class);
System.out.println("IOC 容器创建完成!");
context.close();
}

通过以下测试结果可以确定Spring容器管理(单实例)Bean的过程为:

Bean构造方法–>Bean init()–>IOC容器创建完成–>关闭容器–>Bean销毁

1
2
3
4
5
6
7
8
十二月 09, 2018 9:25:32 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@77556fd: startup date [Sun Dec 09 21:25:32 CST 2018]; root of context hierarchy
Car...Constructor...
Car...init...
IOC 容器创建完成!
十二月 09, 2018 9:25:34 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@77556fd: startup date [Sun Dec 09 21:25:32 CST 2018]; root of context hierarchy
Car...destroy...

1.2.2多实例情况下测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration
public class MainConfigLifeCycle {
@Bean(initMethod = "init", destroyMethod = "destroy")
@Scope(value = "prototype")
public Car car() {
return new Car();
}
}
@Test
public void testLifeCycle() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigLifeCycle.class);
System.out.println("IOC 容器创建完成!");
Car car = (Car) context.getBean("car");
System.out.println(car);
context.close();
}

通过以下测试结果可以确定Spring容器管理(多实例)Bean的过程为(多实例注意:不会调用销毁方法):

IOC容器创建完成–>Bean构造方法–>Bean init()–>关闭容器

1
2
3
4
5
6
7
8
十二月 14, 2018 10:11:55 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@77556fd: startup date [Fri Dec 14 10:11:55 CST 2018]; root of context hierarchy
IOC 容器创建完成!
Car...Constructor...
十二月 14, 2018 10:11:56 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@77556fd: startup date [Fri Dec 14 10:11:55 CST 2018]; root of context hierarchy
Car...init...
com.rocklei123.bean.Car@77e4c80f

2. 实现InitializingBean和DisposableBean接口

Bean实现InitializingBean(定义初始化逻辑);重写afterPropertiesSet()方法,表示构造方法完成后,并且属性赋值完成后执行该方法

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
35
36
37
38
39
40
41
42
43
44
//实体类
package com.rocklei123.bean;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

@Component
public class Cat implements InitializingBean, DisposableBean {

public Cat() {
System.out.println("cat...constructor...");
}

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

@Override
public void afterPropertiesSet() throws Exception {
System.out.println("cat...afterPropertiesSet...");
}
}

//配置类
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(value = "com.rocklei123.bean")
public class MainConfigLifeCycle {

}

//测试类
@Test
public void testLifeCycleByInterface() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigLifeCycle.class);
System.out.println("IOC 容器创建完成!");
Cat cat = (Cat) context.getBean("cat");
System.out.println(cat);
context.close();
}

测试结果:

1
2
3
4
5
6
7
8
9
十二月 14, 2018 3:27:38 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@77556fd: startup date [Fri Dec 14 15:27:37 CST 2018]; root of context hierarchy
cat...constructor...
cat...afterPropertiesSet...
十二月 14, 2018 3:27:41 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@77556fd: startup date [Fri Dec 14 15:27:37 CST 2018]; root of context hierarchy
IOC 容器创建完成!
com.rocklei123.bean.Cat@61009542
cat...destroy...

3. JSR250 @PostConstruct 和@PreDestroy

  • @PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
  • @PreDestroy:在容器销毁bean之前通知我们进行清理工作

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Component
public class Dog {

public Dog() {
System.out.println("dog...Construct...");
}

@PostConstruct
public void init(){}{
System.out.println("dog...init...");
}

@PreDestroy
public void destory(){
System.out.println("dog...destory...");
}
}

测试结果:

1
2
3
4
5
6
7
8
9
10
11
12
十二月 14, 2018 3:33:03 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@77556fd: startup date [Fri Dec 14 15:33:03 CST 2018]; root of context hierarchy
cat...constructor...
cat...afterPropertiesSet...
dog...init...
dog...Construct...
十二月 14, 2018 3:33:07 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@77556fd: startup date [Fri Dec 14 15:33:03 CST 2018]; root of context hierarchy
IOC 容器创建完成!
com.rocklei123.bean.Dog@2ea6137
dog...destory...
cat...destroy...

4. 实现BeanPostProcessor接口

BeanPostProcessor【interface】:Spring 为我们提供的bean的后置处理器;在bean初始化前后进行一些处理工作;同时可以对这个bean进行包装并返回。

  • postProcessBeforeInitialization:在任何初始化方法调用之前工作
  • postProcessAfterInitialization:在任何初始化方法调用之后工作
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
package com.rocklei123.bean;

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

/**
* @ClassName: MyBeanPostProcessor
* @Author: rocklei123
* @Date: 2018/12/14 15:39
* @Description: 后置处理器:初始化前后进行处理工作,将后置处理器加入到容器中
* @Version 1.0
*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanPostProcessor...postProcessBeforeInitialization..." + beanName + "=>" + bean);
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanPostProcessor...postProcessAfterInitialization..." + beanName + "=>" + bean);
return bean;
}
}

//测试代码
@Test
public void testLifeCycleBeanPostProcessor() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigLifeCycle.class);
System.out.println("IOC 容器创建完成!");
context.close();
}

测试结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
十二月 14, 2018 5:09:06 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@77556fd: startup date [Fri Dec 14 17:09:06 CST 2018]; root of context hierarchy
MyBeanPostProcessor...postProcessBeforeInitialization...org.springframework.context.event.internalEventListenerProcessor=>org.springframework.context.event.EventListenerMethodProcessor@7ff2a664
MyBeanPostProcessor...postProcessAfterInitialization...org.springframework.context.event.internalEventListenerProcessor=>org.springframework.context.event.EventListenerMethodProcessor@7ff2a664
MyBeanPostProcessor...postProcessBeforeInitialization...org.springframework.context.event.internalEventListenerFactory=>org.springframework.context.event.DefaultEventListenerFactory@58c1c010
MyBeanPostProcessor...postProcessAfterInitialization...org.springframework.context.event.internalEventListenerFactory=>org.springframework.context.event.DefaultEventListenerFactory@58c1c010
MyBeanPostProcessor...postProcessBeforeInitialization...mainConfigLifeCycle=>com.rocklei123.config.MainConfigLifeCycle$$EnhancerBySpringCGLIB$$a5cb492c@b7f23d9
MyBeanPostProcessor...postProcessAfterInitialization...mainConfigLifeCycle=>com.rocklei123.config.MainConfigLifeCycle$$EnhancerBySpringCGLIB$$a5cb492c@b7f23d9
cat...constructor...
MyBeanPostProcessor...postProcessBeforeInitialization...cat=>com.rocklei123.bean.Cat@3f200884
cat...afterPropertiesSet...
MyBeanPostProcessor...postProcessAfterInitialization...cat=>com.rocklei123.bean.Cat@3f200884
dog...init...
dog...Construct...
MyBeanPostProcessor...postProcessBeforeInitialization...dog=>com.rocklei123.bean.Dog@4d49af10
MyBeanPostProcessor...postProcessAfterInitialization...dog=>com.rocklei123.bean.Dog@4d49af10
十二月 14, 2018 5:09:11 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@77556fd: startup date [Fri Dec 14 17:09:06 CST 2018]; root of context hierarchy
IOC 容器创建完成!
dog...destory...
cat...destroy...

5. Bean 生命周期管理方法总结

  • 1)、指定初始化和销毁方法;通过@Bean指定init-method和destroy-method;
  • 2)、通过让Bean实现InitializingBean(定义初始化逻辑),DisposableBean(定义销毁逻辑);
  • 3)、可以使用JSR250;
    • @PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
    • @PreDestroy:在容器销毁bean之前通知我们进行清理工作
  • 4)、BeanPostProcessor【interface】:bean的后置处理器;
    在bean初始化前后进行一些处理工作;
    • postProcessBeforeInitialization:在初始化之前工作
    • postProcessAfterInitialization:在初始化之后工作

6. BeanPostProcessor介绍与原理

BeanPostProcessor 源码:

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
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory
//给bean进行属性赋值
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
//
this.populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
}
}

//初始化bean
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
AbstractAutowireCapableBeanFactory.this.invokeAwareMethods(beanName, bean);
return null;
}
}, this.getAccessControlContext());
} else {
this.invokeAwareMethods(beanName, bean);
}

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//执行初始化前的方法
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}

try {
//执行自定义初始化
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}

if (mbd == null || !mbd.isSynthetic()) {
//执行初始化之后的方法
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}

BeanPostProcessor核心原理总结

1
2
3
4
5
6
7
populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
initializeBean
{
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

Spring底层大量 BeanPostProcessor 的使用;比如bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async,xxx BeanPostProcessor;

1544780929169

6.1 ApplicationContextAwareProcessor 后置处理器

ApplicationContextAwareProcessor 接口,是Spring容器提供获取IOC容器接口,其内部实现也是后置处理器原理。示例代码:

1
2
3
4
5
6
7
8
public class Dog implements ApplicationContextAware {
private ApplicationContext context;

@Override //业务代码注入IOC容器
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
}

7. Bean生命周期总结

  1. 构造(对象创建)
1
2
* 单实例:在容器启动的时候创建对象
* 多实例:在每次获取的时候创建对象
  1. BeanPostProcessor.postProcessBeforeInitialization
  2. 初始化:
1
* 对象创建完成,并赋值好,调用初始化方法。。。
  1. BeanPostProcessor.postProcessAfterInitialization
  2. 销毁:
1
2
* 单实例:容器关闭的时候
* 多实例:容器不会管理这个bean;容器不会调用销毁方法;

其实Spring容器整个生命周期还有其他几个步骤,下图给出整个Spring容器管理bean的生命周期。

1544501234588

8.欢迎关注米宝窝,持续更新中,谢谢!

米宝窝 https://rocklei123.github.io/

-------------本文结束感谢您的阅读-------------
欢迎持续关注米宝窝,定期更新谢谢! https://rocklei123.github.io/
欢迎持续关注我的CSDN https://blog.csdn.net/rocklei123
rocklei123的技术点滴
熬夜写博客挺辛苦的,生怕猝死,所以每当写博客都带着听诊器,心脏一有异响,随时按Ctrl+S。
rocklei123 微信支付

微信支付

rocklei123 支付宝

支付宝