title: Spring注解驱动开发(二)-Bean的生命周期
author: rocklei123
tags:
Annotation
Spring
Java
categories: Spring
date: 2018-12-09 20:40:48
Bean的生命周期:
bean创建---初始化----销毁的过程
容器管理bean的生命周期;
我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。
1. 指定初始化和销毁方法
1.1 xml方式
<bean id="person" class="com.rocklei123.bean.Person" init-method="" destroy-method="">
</bean>
1.2 注解方式
可通过@Bean(initMethod = "init",destroyMethod = "destroy")指定初始化及销毁方法,通过测试可以确定:
构造对象:
单实例:在容器启动的时候创建对象
多实例:在每次获取的时候创建对象
初始化:
* 对象创建完成,并赋值好,调用初始化方法。
销毁:
单实例:容器关闭的时候
多实例:容器不会管理这个bean;容器不会调用销毁方法;
1.2.1 单实例情况测试
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销毁
十二月 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多实例情况下测试
@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()-->关闭容器
十二月 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(定义销毁逻辑);容器销毁时调用
测试代码:
//实体类
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();
}
测试结果:
十二月 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之前通知我们进行清理工作
示例代码:
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...");
}
}
测试结果:
十二月 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:在任何初始化方法调用之后工作
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();
}
测试结果:
十二月 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 源码:
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核心原理总结
populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
initializeBean
{
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
Spring底层大量 BeanPostProcessor 的使用;比如bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async,xxx BeanPostProcessor;

6.1 ApplicationContextAwareProcessor 后置处理器
ApplicationContextAwareProcessor 接口,是Spring容器提供获取IOC容器接口,其内部实现也是后置处理器原理。示例代码:
public class Dog implements ApplicationContextAware {
private ApplicationContext context;
@Override //业务代码注入IOC容器
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
}
7. Bean生命周期总结
构造(对象创建)
* 单实例:在容器启动的时候创建对象
* 多实例:在每次获取的时候创建对象
BeanPostProcessor.postProcessBeforeInitialization
初始化:
* 对象创建完成,并赋值好,调用初始化方法。。。
BeanPostProcessor.postProcessAfterInitialization
销毁:
* 单实例:容器关闭的时候
* 多实例:容器不会管理这个bean;容器不会调用销毁方法;
其实Spring容器整个生命周期还有其他几个步骤,下图给出整个Spring容器管理bean的生命周期。

8.欢迎关注米宝窝,持续更新中,谢谢!
米宝窝 https://rocklei123.github.io/




