目录
一、Bean的初始化和销毁
1、@Bean指定初始化和销毁方法
2、通过实现InitializingBean和Disposabean来初始化和销毁bean
3、使用JSR250定义的@PostConstruct&@PreDestroy注解来创建和销毁bean
4、BeanPostProcessor-后置处理器(全局)
5、生命周期总结
二、BeanPostProcessor原理
1、BeanPostProcessor原理
2、spring底层对BeanPostProcessor的使用
一、Bean的初始化和销毁
1、@Bean指定初始化和销毁方法
(1)定义bean类
package com.xiang.spring.bean;
public class Car {
public Car() {
System.out.println("car constructor ...");
}
public void init() {
System.out.println("car init ...");
}
public void destory() {
System.out.println("car destory ...");
}
}
(2)编写配置类
package com.xiang.spring.config;
import com.xiang.spring.bean.Car;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
/**
* bean的生命周期(由容器管理):
* bean创建——初始化——销毁
* 可以自定义初始化和销毁方法,容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。
*
* 构造(创建对象):
* 单实例:在容器启动的时候创建对象
* 多实例:在每次获取的时候创建对象
* 初始化:
* 对象创建完成,并赋值好,调用初始化方法。
* 销毁:
* 单实例bean:在容器关闭时进行销毁。
* 多实例bean:容器不会管理bean,容器不会调用销毁方法。
*
* 1、指定初始化和销毁方法:
* 通过@Bean指定init-method和destroy-method
*
*/
@Configuration
public class MainConfigOfLifeCycle {
//@Scope("prototype")
@Bean(initMethod = "init", destroyMethod = "destory")
public Car car() {
return new Car();
}
}
(3)测试程序
@Test
public void test01() {
// 创建ioc容器,容器创建时,默认会将单例的bean都创建出来
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("容器创建完成");
applicationContext.getBean("car");
// 容器关闭 就会销毁bean
applicationContext.close();
}
//执行结果
car constructor ...
car init ...
容器创建完成
car destory ...
2、通过实现InitializingBean和Disposabean来初始化和销毁bean
(1)定义bean类
package com.xiang.spring.bean;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class Cat implements InitializingBean, DisposableBean {
public Cat() {
System.out.println("cat construator");
}
// 销毁
public void destroy() throws Exception {
System.out.println("cat destroy");
}
// 初始化
public void afterPropertiesSet() throws Exception {
System.out.println("cat init");
}
}
(2)配置类
@Bean
public Cat cat() {
return new Cat();
}
(3)测试类
@Test
public void test01() {
// 创建ioc容器,容器创建时,默认会将单例的bean都创建出来
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("容器创建完成");
// 容器关闭 就会销毁bean
applicationContext.close();
}
// 运行结果
cat construator
cat init
容器创建完成
cat destroy
3、使用JSR250定义的@PostConstruct&@PreDestroy注解来创建和销毁bean
(1)定义bean
package com.xiang.spring.bean;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Component
public class Dog {
public Dog() {
System.out.println("dog constructor ...");
}
// 对象创建并赋值之后调用
@PostConstruct
public void init() {
System.out.println("dog PostConstruct ...");
}
// 容器移除对象之前调用
@PreDestroy
public void destory() {
System.out.println("dog PreDestroy ...");
}
}
(2)测试查看结果
@Test
public void test01() {
// 创建ioc容器,容器创建时,默认会将单例的bean都创建出来
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("容器创建完成");
// 容器关闭 就会销毁bean
applicationContext.close();
}
dog constructor ...
dog PostConstruct ...
容器创建完成
dog PreDestroy ...
4、BeanPostProcessor-后置处理器(全局)
(1)编写自定义BeanPostProcessor
package com.xiang.spring.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/**
* 后置处理器:初始化前后进行工作
* 方法返回值:包装好的bean
*/
//@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + " - MyBeanPostProcessor - postProcessBeforeInitialization");
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + "MyBeanPostProcessor - postProcessAfterInitialization");
return bean;
}
}
(2)测试查看结果
可以看出来,所有的bean都在初始化前后执行了postProcessBeforeInitialization和postProcessAfterInitialization。
@Test
public void test01() {
// 创建ioc容器,容器创建时,默认会将单例的bean都创建出来
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("容器创建完成");
// 容器关闭 就会销毁bean
applicationContext.close();
}
// 运行结果
org.springframework.context.event.internalEventListenerProcessor - MyBeanPostProcessor - postProcessBeforeInitialization
org.springframework.context.event.internalEventListenerProcessorMyBeanPostProcessor - postProcessAfterInitialization
org.springframework.context.event.internalEventListenerFactory - MyBeanPostProcessor - postProcessBeforeInitialization
org.springframework.context.event.internalEventListenerFactoryMyBeanPostProcessor - postProcessAfterInitialization
mainConfigOfLifeCycle - MyBeanPostProcessor - postProcessBeforeInitialization
mainConfigOfLifeCycleMyBeanPostProcessor - postProcessAfterInitialization
dog constructor ...
dog - MyBeanPostProcessor - postProcessBeforeInitialization
dog PostConstruct ...
dogMyBeanPostProcessor - postProcessAfterInitialization
car constructor ...
car - MyBeanPostProcessor - postProcessBeforeInitialization
car init ...
carMyBeanPostProcessor - postProcessAfterInitialization
cat construator
cat - MyBeanPostProcessor - postProcessBeforeInitialization
cat init
catMyBeanPostProcessor - postProcessAfterInitialization
容器创建完成
cat destroy
car destory ...
dog PreDestroy ...
5、生命周期总结
bean的生命周期(由容器管理):
bean创建——初始化——销毁
可以自定义初始化和销毁方法,容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。
构造(创建对象):
单实例:在容器启动的时候创建对象
多实例:在每次获取的时候创建对象
初始化:
对象创建完成,并赋值好,调用初始化方法。
销毁:
单实例bean:在容器关闭时进行销毁。
多实例bean:容器不会管理bean,容器不会调用销毁方法。
① 、指定初始化和销毁方法:
通过@Bean指定init-method和destroy-method
② 、通过让bean实现InitializingBean(定义初始化逻辑)
实现DisposableBean(定义销毁逻辑)
③ 、可以使用JSR250:
@PostConstruct:在bean创建完成并且属性赋值完成后,来执行初始化
@PreDestroy:在容器销毁bean之前,通知我们进行清理工作
④ 、BeanPostProcessor接口:bean的后置处理器:
在bean初始化前后进行一些处理工作。
postProcessBeforeInitialization:在初始化之前工作
postProcessAfterInitialization:在初始化之后工作
二、BeanPostProcessor原理
1、BeanPostProcessor原理
遍历得到容器中所有的BeanPostProcessor,挨个执行beforeInitialization,一旦返回null,跳出for循环,不会执行后面的BeanPostProcessor。
源码中是先执行populateBean方法进行属性赋值、再执行postProcessBeforeInitialization方法,再执行初始化方法、再执行postProcessAfterInitialization方法。
/**
* 初始化bean的完整源码
*/
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
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()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
2、spring底层对BeanPostProcessor的使用
bean赋值,注入其他组件、@Autowired、生命周期注解功能、@Async、等等很多功能都用到了BeanPostProcessor。