容器管理bean的生命周期:
我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
构造(对象创建):
对于单实例:在容器启动的时候创建对象,容器关闭时,会调用其destroy方法
对于多实例:在每次获取的时候创建对象,容器不管理该bean的生命周期(即:在容器关闭的时候,该bean不会调用destroy()方法)
初始化:在对象创建完成,并属性赋值好后,调用初始化方法
销毁:
对于单实例:容器关闭时,会调用destroy()方法
对于多实例:容器不会管理这个bean,容器关闭时,不会调用destroy()方法
四种方式:
1、指定初始化和销毁方法,好处是自定义数据属性赋值
以前是在xml配置中通过init-method="" destory-method="" 来指定
在注解开发时,在@Bean注解中用initMethod=""和destroyMethod=""来指定
例子:
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...");
}
}
在配置类中
@Bean(initMethod="init",destroyMethod="destroy")
public Car car() {
return new Car();
}
2、通过让Bean实现InitializingBean接口重写afterPropertiesSet()来定义初始化逻辑,实现DisposableBean接口重写destroy()来定
义销毁逻辑。(因为这里的Cat采用了@Component注解,所以不需要再配置里用@Bean注册,只需要在配置类用@ComponentScan扫描相应的包即可)
例子:
@Component
public class Cat implements InitializingBean, DisposableBean{
/*
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
System.out.println("cat...afterPropertiesSet...");
}
/*
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
@Override
public void destroy() throws Exception {
// TODO Auto-generated method stub
System.out.println("cat...destroy...");
}
}
3、可以使用JSR250
@PostConstruct:在bean创建完成并且属性赋值完成后执行初始化方法
@PreDestroy:在容器销毁bean之前通知我们进行清理工作
例子:
@Component
public class Dog {
public Dog() {
System.out.println("Dog....Constructor....");
}
@PostConstruct
public void init() {
System.out.println("Dog....Constructor...PostConstruct");
}
@PreDestroy
public void destroy() {
System.out.println("Dog....Constructor...Predestroy");
}
}
4、BeanPostProcessor接口:(bean的后置处理器),即:在bean(这里的bean加入容器的所有bean,而不是某单个bean)初始化前后进行一些处理工作
postProcessBeforeInitialization:在初始化之前工作
postProcessAfterInitialization:在初始化之后工作
例子:
@Component
public class MyBeanPostProcessor implements BeanPostProcessor{
/*
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
(java.lang.Object, java.lang.String)
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("postProcessBeforeInitialization:"+beanName+"->"+bean);
return bean;
}
/*
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
(java.lang.Object, java.lang.String)
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("postProcessAfterInitialization:"+beanName+"->"+bean);
return bean;
}
}
打印结果:
postProcessBeforeInitialization:org.springframework.context.event.internalEventListenerProcessor->org.springframework.context.event.EventListenerMethodProcessor@f0f2775
postProcessAfterInitialization:org.springframework.context.event.internalEventListenerProcessor->org.springframework.context.event.EventListenerMethodProcessor@f0f2775
postProcessBeforeInitialization:org.springframework.context.event.internalEventListenerFactory->org.springframework.context.event.DefaultEventListenerFactory@6591f517
postProcessAfterInitialization:org.springframework.context.event.internalEventListenerFactory->org.springframework.context.event.DefaultEventListenerFactory@6591f517
postProcessBeforeInitialization:mainConfigOfLifeCycle->com.hpcds.config.MainConfigOfLifeCycle$$EnhancerBySpringCGLIB$$e15c7c0e@429bd883
postProcessAfterInitialization:mainConfigOfLifeCycle->com.hpcds.config.MainConfigOfLifeCycle$$EnhancerBySpringCGLIB$$e15c7c0e@429bd883
postProcessBeforeInitialization:cat->com.hpcds.bean.Cat@58134517
cat...afterPropertiesSet...
postProcessAfterInitialization:cat->com.hpcds.bean.Cat@58134517
Dog....Constructor....
postProcessBeforeInitialization:dog->com.hpcds.bean.Dog@7fe8ea47
Dog....Constructor...PostConstruct
postProcessAfterInitialization:dog->com.hpcds.bean.Dog@7fe8ea47
car constructor...
postProcessBeforeInitialization:car->com.hpcds.bean.Car@36f0f1be
Car init...
postProcessAfterInitialization:car->com.hpcds.bean.Car@36f0f1be
容器创建完成。。。。
十二月 01, 2018 9:35:17 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@512ddf17: startup date [Sat Dec 01 21:35:16 CST 2018]; root of context hierarchy
Car destroy...
Dog....Constructor...Predestroy
cat...destroy...
解释:前面是IOC容器的默认组件前跟后的相应操作,此后的Car,Cat,Dog这些bean,在初始化工作完成之前跟之后都会进行拦截并采取相应的操作。
即:
在初始化之前,调用BeanPostProcessor.postProcessBeforeInitialization
初始化:在对象创建完成,并属性赋值好后,调用初始化方法
在初始化之后,调用BeanPostProcessor.postProcessAfterInitialization
Spring底层中会遍历得到容器中所有的BeanPostProcessor,挨个执行BeforeInitialization,一旦返回null,跳出for循环,不会执行BeanPostProcessor.postProcessBeforeInitialization
BeanPostProcessor的原理:
populateBean(beanName, mbd, instanceWrapper);//给bean进行属性赋值的
initializeBean//属性赋值完成后进行
{
//以下操作都是在populateBean之后进行的
applyBeanPostProcessorBeforeInitialization(wrappedBean, beanName);
invokeInitMethods(beanName, wrappedBean, mbd); 执行自定义初始化方法
applyBeanPostProcessorAfterInitialization(wrappedBean, beanName);
}
Spring底层对BeanPostProcessor的使用:bean赋值,注入其他组件,解析其他注解等等。