文章目录
1 Bean的生命周期
bean的声明周期:
- 创建
- 初始化
- 销毁
我们可以自定义初始化和销毁方法,容器在bean执行到当前生命周期的时候来调用自己定义的初始化和销毁逻辑
为了演示bean声明周期,将在创建一个新的包,用于测试演示。
1.1 创建
之前已经提过:
单实例:在容器启动的时候创建
多实例:在每次获取的时候创建
1.2 初始化
单实例:对象创建完,并赋值好,调用初始化方法
多实例:对象创建完,并赋值好,调用初始化方法
1.3 销毁
单实例:容器关闭的时候执行销毁逻辑
多实例:容器不会管理这个Bean,容器不会调用销毁方法,需要自己手动调用
2 @Bean注解中指定初始化和销毁方法
在@bean
注解的时候介绍过一次,通过initMethod
和destroyMethod
指定初始化方法和销毁方法
定义一个bean
package study.wyy.spring.anno.life.bean;
/**
* @author wyaoyao
* @data 2020-11-23 07:49
*/
public class LifeBean {
/**
* 构造方法
*/
public LifeBean() {
System.out.println("LifeBean constructor。。。");
}
/**
* 初始化方法
*/
public void init(){
System.out.println("LifeBean init。。。");
}
/**
* 销毁方法
*/
public void destroy(){
System.out.println("LifeBean destroy。。。");
}
}
使用bean注解注入容器,并指定初始化和销毁方法
package study.wyy.spring.anno.life.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import study.wyy.spring.anno.life.bean.LifeBean;
/**
* @author wyaoyao
* @data 2020-11-23 07:51
*/
@Configuration
public class SpringConfig {
@Bean(initMethod = "init",destroyMethod = "destroy")
public LifeBean lifeBean(){
return new LifeBean();
}
}
测试
@org.junit.Test
public void test01(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
System.out.println("ioc容器创建完成");
context.close();
}
输出结果
LifeBean constructor。。。
LifeBean init。。。
ioc容器创建完成
LifeBean destroy。。。
上面测试的是单实例bean的生命周期
可见在单实例在容器创建完成时,就完成单实例bean的创建和初始化
那何时销毁呢—>在容器关闭的时候。
下面测试多实例bean的声明周期,使用@Scope注解
package study.wyy.spring.anno.life.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import study.wyy.spring.anno.life.bean.LifeBean;
/**
* @author wyaoyao
* @data 2020-11-23 07:51
*/
@Configuration
public class SpringConfig1 {
@Bean(initMethod = "init",destroyMethod = "destroy")
@Scope("prototype")
public LifeBean lifeBean(){
return new LifeBean();
}
}
测试
@org.junit.Test
public void test02(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig1.class);
System.out.println("ioc容器创建完成");
context.close();
}
输出
ioc容器创建完成
可见多实例的时候在创建ioc容器的时候不会创建bean
@org.junit.Test
public void test03(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig1.class);
System.out.println("ioc容器创建完成");
LifeBean bean = context.getBean(LifeBean.class);
context.close();
}
输出
ioc容器创建完成
LifeBean constructor。。。
LifeBean init。。。
发现多实例在每次获取的时候执行创建和初始化,但是容器关闭的时候不会执行销毁逻辑
3 InitializingBean , DisposableBean
3.1 介绍
public interface InitializingBean {
/**
* Invoked by a BeanFactory after it has set all bean properties supplied
* (and satisfied BeanFactoryAware and ApplicationContextAware).
* <p>This method allows the bean instance to perform initialization only
* possible when all bean properties have been set and to throw an
* exception in the event of misconfiguration.
* @throws Exception in the event of misconfiguration (such
* as failure to set an essential property) or if initialization fails.
*/
// bean的属性设置完成之后执行
void afterPropertiesSet() throws Exception;
}
public interface DisposableBean {
/**
* Invoked by a BeanFactory on destruction of a singleton.
* @throws Exception in case of shutdown errors.
* Exceptions will get logged but not rethrown to allow
* other beans to release their resources too.
*/
// 销毁的时候执行
void destroy() throws Exception;
}
3.2 演示
定义一个Bean实现这两个接口
package study.wyy.spring.anno.life.bean;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
/**
* @author wyaoyao
* @data 2020-11-23 07:49
*/
public class LifeBean2 implements InitializingBean, DisposableBean {
/**
* 构造方法
*/
public LifeBean2() {
System.out.println("LifeBean2 constructor。。。");
}
/**
* 销毁方法
*/
@Override
public void destroy(){
System.out.println("LifeBean2 destroy。。。");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("LifeBean2 afterPropertiesSet。。。");
}
}
注入容器
package study.wyy.spring.anno.life.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import study.wyy.spring.anno.life.bean.LifeBean2;
/**
* @author wyaoyao
* @data 2020-11-23 07:51
*/
@Configuration
public class SpringConfig2 {
@Bean
public LifeBean2 lifeBean(){
return new LifeBean2();
}
}
测试
@org.junit.Test
public void test04(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig2.class);
System.out.println("ioc容器创建完成");
context.close();
}
输出
LifeBean2 constructor。。。
LifeBean2 afterPropertiesSet。。。
ioc容器创建完成
LifeBean2 destroy。。。
测试多实例
package study.wyy.spring.anno.life.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import study.wyy.spring.anno.life.bean.LifeBean2;
/**
* @author wyaoyao
* @data 2020-11-23 07:51
*/
@Configuration
public class SpringConfig3 {
@Bean
@Scope("prototype")
public LifeBean2 lifeBean(){
return new LifeBean2();
}
}
@org.junit.Test
public void test05(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig3.class);
System.out.println("ioc容器创建完成");
LifeBean2 bean = context.getBean(LifeBean2.class);
context.close();
}
ioc容器创建完成
LifeBean2 constructor。。。
LifeBean2 afterPropertiesSet。。。
4 JSR250
@PostConstruct
: bean创建完成并属性赋值完成的时候执行@PreDestroy
: 容器销毁的对象的前通知
定义一个bean
package study.wyy.spring.anno.life.bean;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* @author wyaoyao
* @data 2020-11-23 08:10
*/
public class LifeBean3 {
public LifeBean3() {
System.out.println("LifeBean3 constructor。。。");
}
/**
* 容器销毁的对象的前通知
* @throws Exception
*/
@PreDestroy
public void destroy() throws Exception {
System.out.println("LifeBean3 destroy。。。");
}
/**
* bean创建完成并属性赋值完成的时候执行
* @throws Exception
*/
@PostConstruct
public void afterPropertiesSet() throws Exception {
System.out.println("LifeBean3 afterPropertiesSet。。。");
}
}
注入容器
package study.wyy.spring.anno.life.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import study.wyy.spring.anno.life.bean.LifeBean2;
import study.wyy.spring.anno.life.bean.LifeBean3;
/**
* @author wyaoyao
* @data 2020-11-23 07:51
*/
@Configuration
public class SpringConfig4 {
@Bean
public LifeBean3 lifeBean(){
return new LifeBean3();
}
}
测试
@org.junit.Test
public void test06(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig4.class);
System.out.println("ioc容器创建完成");
LifeBean3 bean = context.getBean(LifeBean3.class);
context.close();
}
输出
LifeBean3 constructor。。。
LifeBean3 afterPropertiesSet。。。
ioc容器创建完成
LifeBean3 destroy。。。
5 三者比较
上述提供的3个初始化和销毁的方式,这三个之间的顺序又是如何呢
一个Bean通过上面三个方式进行初始化
package study.wyy.spring.anno.life.config;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* @author wyaoyao
* @data 2020-11-23 08:14
*/
public class LifeBean4 implements InitializingBean, DisposableBean {
public LifeBean4() {
System.out.println("LifeBean4 constructor。。。");
}
/**
* 销毁的时候执行
* @throws Exception
*/
@Override
public void destroy() throws Exception {
System.out.println("LifeBean4 destroy。。。");
}
/**
* bean的属性设置完成之后执行
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("LifeBean4 afterPropertiesSet。。。");
}
@PostConstruct
public void postConstruct(){
System.out.println("LifeBean4 postConstruct。。。");
}
@PreDestroy
public void preDestroy(){
System.out.println("LifeBean4 preDestroy。。。");
}
public void init(){
System.out.println("LifeBean4 init。。。");
}
public void destroyOnBean(){
System.out.println("LifeBean4 destroyOnBean。。。");
}
}
配置
package study.wyy.spring.anno.life.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import study.wyy.spring.anno.life.bean.LifeBean3;
/**
* @author wyaoyao
* @data 2020-11-23 07:51
*/
@Configuration
public class SpringConfig5 {
@Bean(initMethod = "init",destroyMethod = "destroyOnBean")
public LifeBean4 lifeBean(){
return new LifeBean4();
}
}
测试
@org.junit.Test
public void test07(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig5.class);
System.out.println("ioc容器创建完成");
LifeBean4 bean = context.getBean(LifeBean4.class);
context.close();
}
输出
LifeBean4 constructor。。。
LifeBean4 postConstruct。。。
LifeBean4 afterPropertiesSet。。。
LifeBean4 init。。。
ioc容器创建完成
LifeBean4 preDestroy。。。
LifeBean4 destroy。。。
LifeBean4 destroyOnBean。。。
可见初始化和销毁的时候这三个顺序:
@postConstruct
InitializingBean
@Bean
6 BeanPostProcessor
6.1 BeanPostProcessor介绍
可以对Spring容器扫描到的Bean在初始化前后进行增强处理
public interface BeanPostProcessor {
/**
*
* @param bean : 当前的处理Bean
* @param beanName 当前Bean的name
* @return 可以返回当前的Bean也可以返回当前Bean的包装
* @throws BeansException
* 初始化(afterPropertiesSet,init-method)之前
*/
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
*
* @param bean 当前的处理Bean
* @param beanName 当前Bean的name
* @return 可以返回当前的Bean也可以返回当前Bean的包装
* @throws BeansException
* 初始化(afterPropertiesSet,init-method)之后
*/
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
6.2 BeanPostProcessor测试
只对LifeBean4类型进行增强
package study.wyy.spring.anno.life.spi;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import study.wyy.spring.anno.life.bean.LifeBean4;
/**
* @author wyaoyao
* @data 2020-11-23 08:21
* BeanPostProcessor:Bean初始化前后进行增强处理
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
/**
*
* @param bean : 当前的处理Bean
* @param beanName 当前Bean的name
* @return 可以返回当前的Bean也可以返回当前Bean的包装
* @throws BeansException
* 初始化之前
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof LifeBean4){
// 只对LifeBean4类型进行增强
System.out.println("BeanPostProcessor "+ beanName +"postProcessBeforeInitialization 。。。");
}
return bean;
}
/**
*
* @param bean 当前的处理Bean
* @param beanName 当前Bean的name
* @return 可以返回当前的Bean也可以返回当前Bean的包装
* @throws BeansException
* 初始化之后
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof LifeBean4){
// 只对LifeBean4类型进行增强
System.out.println("BeanPostProcessor "+ beanName +"postProcessAfterInitialization 。。。");
}
return bean;
}
}
配置
package study.wyy.spring.anno.life.config;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import study.wyy.spring.anno.life.bean.LifeBean4;
import study.wyy.spring.anno.life.spi.MyBeanPostProcessor;
/**
* @author wyaoyao
* @data 2020-11-23 07:51
*/
@Configuration
public class SpringConfig6 {
@Bean(initMethod = "init",destroyMethod = "destroyOnBean")
public LifeBean4 lifeBean(){
return new LifeBean4();
}
@Bean
public BeanPostProcessor myBeanPostProcessor(){
return new MyBeanPostProcessor();
}
}
测试
@org.junit.Test
public void test08(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig6.class);
System.out.println("ioc容器创建完成");
LifeBean4 bean = context.getBean(LifeBean4.class);
context.close();
}
输出
LifeBean4 constructor。。。
BeanPostProcessor lifeBeanpostProcessBeforeInitialization 。。。
LifeBean4 postConstruct。。。
LifeBean4 afterPropertiesSet。。。
LifeBean4 init。。。
BeanPostProcessor lifeBeanpostProcessAfterInitialization 。。。
ioc容器创建完成
LifeBean4 preDestroy。。。
LifeBean4 destroy。。。
LifeBean4 destroyOnBean。。。
可以看到BeanPostProcessor的执行时机是在:构造之后,初始化方法前后执行