@Bean 生命周期
bean生命周期:
实例bean
1.当调用者通过getBean(beanName)向容器请求某一个Bean时,如果容器注册了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor接口,在实例化Bean之前,将调用接口的postProcessBeforeInstantiation()方法;
2.根据配置情况调用Bean构造函数或工厂方法实例化Bean;
3.如果容器注册了InstantiationAwareBeanPostProcessor接口,在实例化Bean之后,调用该接口的postProcessAfterInstantiation()方法,可在这里对已经实例化的对象进行一些"梳妆打扮";
4.如果Bean配置了属性信息,容器在这一步着手将配置值设置到Bean对应的属性中,不过在设置每个属性之前将先调用InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues()方法;
**
**
初始化和使用bean
1:BeanNameAware的setBeanName():
如果Bean类有实现org.springframework.beans.BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。
2:BeanFactoryAware的setBeanFactory():
如果Bean类有实现org.springframework.beans.factory.BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。
3:BeanPostProcessors的ProcessBeforeInitialization()
如果有org.springframework.beans.factory.config.BeanPostProcessors和Bean关联,那么其postProcessBeforeInitialization()方法将被将被调用。
4:initializingBean的afterPropertiesSet():
如果Bean类已实现org.springframework.beans.factory.InitializingBean接口,则执行他的afterProPertiesSet()方法
5:Bean定义文件中定义init-method:
可以在Bean定义文件中使用"init-method"属性设定方法名称例如:
如果有以上设置的话,则执行到这个阶段,就会执行initBean()方法
6:BeanPostProcessors的ProcessaAfterInitialization()
如果有任何的BeanPostProcessors实例与Bean实例关联,则执行BeanPostProcessors实例的ProcessaAfterInitialization()方法
BeanPostProcessor后处理器定义了两个方法:
** 其一是postProcessBeforeInitialization()在第8步调用;其二是Object postProcessAfterInitialization(Object bean, String beanName)方法,这个方法在此时调用,容器再次获得对Bean进行加工处理的机会;**
** 如果在中指定Bean的作用范围为scope="prototype",将Bean返回给调用者,调用者负责Bean后续生命的管理,Spring不再管理这个Bean的生命周期。如果作用范围设置为scope="singleton",则将Bean放入到Spring IoC容器的缓存池中,并将Bean引用返回给调用者,Spring继续对这些Bean进行后续的生命管理;**
销毁bean
此时,Bean已经可以被应用系统使用,并且将保留在BeanFactory中知道它不在被使用。有两种方法可以将其从BeanFactory中删除掉
1:DisposableBean的destroy()
在容器关闭时,如果Bean类有实现org.springframework.beans.factory.DisposableBean接口,则执行他的destroy()方法
2:Bean定义文件中定义destroy-method
在容器关闭时,可以在Bean定义文件中使用"destroy-method"属性设定方法名称,例如:
如果有以上设定的话,则进行至这个阶段时,就会执行destroy()方法,如果是使用ApplicationContext来生成并管理Bean的话则稍有不同,使用ApplicationContext来生成及管理Bean实例的话,在执行BeanFactoryAware的setBeanFactory()阶段后,若Bean类上有实现org.springframework.context.ApplicationContextAware接口,则执行其setApplicationContext()方法,接着才执行BeanPostProcessors的ProcessBeforeInitialization()及之后的流程。
代码:
package com.company; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValues; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import java.beans.PropertyDescriptor; public class Main{ public static void main(String[] args) { //①下面两句装载配置文件并启动容器 Resource res = new ClassPathResource("beans.xml"); BeanFactory bf = new XmlBeanFactory(res); //②向容器中注册MyBeanPostProcessor后处理器 ((ConfigurableBeanFactory)bf).addBeanPostProcessor(new MyBeanPostProcessor()); //③向容器中注册MyInstantiationAwareBeanPostProcessor后处理器 ((ConfigurableBeanFactory)bf).addBeanPostProcessor( new MyInstantiationAwareBeanPostProcessor()); //④第一次从容器中获取worker,将触发容器实例化该Bean,这将引发Bean生命周期方法的调用。 Worker worker1 = (Worker)bf.getBean("worker"); System.out.println("第一次从容器中获取worker"); worker1.printInfo(); System.out.println("修改第一次从容器中获取worker的workType"); worker1.setWorkType("正式工"); System.out.println("第一次从容器中获取worker(修改过后的)"); worker1.printInfo(); //⑤第二次从容器中获取worker,直接从缓存池中获取 System.out.println("第二次从容器中获取worker"); Worker worker2= (Worker)bf.getBean("worker"); worker2.printInfo(); //⑥查看worker1和worker2是否指向同一引用 System.out.println("查看worker1和worker2是否指向同一引用 "); System.out.println("worker1==worker2:"+(worker1==worker2)); //⑦关闭容器 ((XmlBeanFactory)bf).destroySingletons(); } } //①管理Bean生命周期的接口 class Worker implements BeanFactoryAware,BeanNameAware,InitializingBean,DisposableBean { private String name; private String workType; private int salary; public BeanFactory beanFactory; private String beanName; public void Worker(){ System.out.println("调用worker()构造函数"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getWorkType() { return workType; } public void setWorkType(String workType) { this.workType = workType; } public int getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } public void printInfo() { System.out.println("name:" + name + ";workType:" + workType + ";salary:" + salary); } //⑤DisposableBean接口方法 @Override public void destroy() throws Exception { System.out.println("----------------销毁bean----------------------"); System.out.println("调用DisposableBean.destroy()。"); } //④InitializingBean接口方法 @Override public void afterPropertiesSet() throws Exception { System.out.println("调用InitializingBean.afterPropertiesSet()。"); } //③BeanNameAware接口方法 @Override public void setBeanName(String arg0) { System.out.println("----------------初始化bean----------------------"); System.out.println("调用BeanNameAware.setBeanName()。"); this.beanName = arg0; } //②BeanFactoryAware接口方法 @Override public void setBeanFactory(BeanFactory arg0) throws BeansException { System.out.println("调用BeanFactoryAware.setBeanFactory()。"); this.beanFactory = arg0; } //⑥通过<bean>的init-method属性指定的初始化方法 public void myInit() { System.out.println("调用init-method所指定的myInit(),将salary设置为600。"); this.salary = 600; } //⑦通过<bean>的destroy-method属性指定的销毁方法 public void myDestroy() { System.out.println("调用destroy-method所指定的myDestroy()。"); } } class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("worker")){ Worker worker = (Worker)bean; if(worker.getWorkType() == null){ System.out.println("调用BeanPostProcessor.postProcess AfterInitialization(), getWorkType为空,设置为默认临时工"); worker.setWorkType("临时工"); } } return bean; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("worker")){ Worker worker = (Worker)bean; if(worker.getSalary() >= 1000){ System.out.println("调用BeanPostProcessor.postProcess BeforeInitialization(), 将salary调整为800。"); worker.setSalary(800); } } return bean; } } class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { // ①接口方法:在实例化Bean前进行调用 public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException { System.out.println("----------------实例化bean----------------------"); // ①-1仅对容器中worker Bean进行处理 if ("worker".equals(beanName)) { System.out .println("InstantiationAware BeanPostProcessor. postProcess BeforeInstantiation"); } return null; } // ②接口方法:在实例化Bean后调用 public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { // ②-1仅对容器中car Bean进行处理 if ("worker".equals(beanName)) { System.out .println("InstantiationAware BeanPostProcessor.postProcess AfterInstantiation"); } return true; } // ③接口方法:在设置某个属性时调用 public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { // ③-1仅对容器中wroker Bean进行处理,还可以通过pdst入参进行过滤, // 仅对car的某个特定属性时进行处理。 if ("worker".equals(beanName)) { System.out .println("Instantiation AwareBeanPostProcessor.postProcess PropertyValues"); } return pvs; } }
beans.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="worker" class="com.company.Worker" init-method="myInit" destroy-method="myDestroy" p:name="小强" p:salary="1000" /> </beans>
Result:
----------------实例化bean---------------------- InstantiationAware BeanPostProcessor. postProcess BeforeInstantiation InstantiationAware BeanPostProcessor.postProcess AfterInstantiation Instantiation AwareBeanPostProcessor.postProcess PropertyValues ----------------初始化bean---------------------- 调用BeanNameAware.setBeanName()。 调用BeanFactoryAware.setBeanFactory()。 调用BeanPostProcessor.postProcess BeforeInitialization(), 将salary调整为800。 调用InitializingBean.afterPropertiesSet()。 调用init-method所指定的myInit(),将salary设置为600。 调用BeanPostProcessor.postProcess AfterInitialization(), getWorkType为空,设置为默认临时工 第一次从容器中获取worker name:小强;workType:临时工;salary:600 修改第一次从容器中获取worker的workType 第一次从容器中获取worker(修改过后的) name:小强;workType:正式工;salary:600 第二次从容器中获取worker name:小强;workType:正式工;salary:600 查看worker1和worker2是否指向同一引用 worker1==worker2:true ----------------销毁bean---------------------- 调用DisposableBean.destroy()。 调用destroy-method所指定的myDestroy()。
http://www.kancloud.cn/evankaka/springlearning/119661
http://www.imooc.com/article/19449
https://my.oschina.net/guanhe/blog/1408505
http://blog.csdn.net/mack415858775/article/details/47721909
https://zhuanlan.zhihu.com/p/25459839
https://muyinchen.github.io/2017/08/23/Spring5%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90-@Autowired/
http://www.shangyang.me/2017/04/05/spring-core-container-sourcecode-analysis-annotation-autowired/