1.1 BeanFactory中bean生命周期图
具体过程如下:
(1) 当调用者通过getBean(beanName)向容器中请求一个Bean时,如果容器注册了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor 接口
则在实例化Bean之前调用接口的 postProcessBeforeInstantiation()方法
(2)根据配置情况调用Bean的构造方法或工厂方法实例化Bean
(3)如果容器注册了InstantiationAwarePostProcessor接口,那么在实例化Bean之后,调用接口depostProcessAfterInstantiation()方法 ,可在这里对已经实例化的对象惊醒梳妆打扮
(4)如果Bean设置了属性信息,那么容器在这一步着手将配置信息设置到Bean对应的属性中,不过在调用每个属性之前将先调用InstantiationAwareBeanPostProcessor接口的postPropertyValues()方法
(5)调用Bean属性设置方法设置属性值
(6)如果Bean实现了org.springframework.beans.factory.BeanNameAware接口,则将调用setBeanName()方法,将配置文件中该Bean对应的名称设置到Bean中
(7)如果Bean实现了org.springframework.beans.factory.BeanFactoryAware接口,则将调用setBeanFactory()接口方法,将BeanFactory实例设置到Bean中
(8)如果BeanFactory装配了org.springframework.beans.factory.config.BeanPostProcessor后处理器,则将调用BeanPostProcessor的Object postProcessBeforeInitialization(Object bean,String beanName) 其中bean表示实例化的对象,beanName表示此对象的名称,返回的对象为加工处理后的Bean.在此方法中用户可以对某些Bean进行特殊处理,甚至改变Bean的行为, Spring中各种神奇的功能都通过BeanPostProcessor来实现
(9)如果Bean实现了IntializingBean接口,则将调用接口的afterPropertiesSet()方法
(10)如果在Bean中通过init-method属性定义初始化方法,则将执行这个方法
(11)BeanPostProcessor后处理器的第二个方法 ,容器再次获得对Bean的加工处理机会,postProcessAfterInitialization(Object bean,String beanName) 类似与(8)
(12)如果<bean>中指定Bean的作用范围为scope="prototype" ,则将Bean交给调用者,由调用者负责Bean的后续生命管理。如果scope="singleton",那么此实例将会被放入缓存池中,有spring容器负责Bean的生命管理
(13) 对于scope="singleton" 的Bean(默认情况) ,当容器关闭时,将触发Spring对Bean后续生命周期管理工作,如果Bean实现DisposableBean接口,那么将会调用destory()方法,释放资源,记录日志文件
(14)如果Bean中通过destory-method属性定义了销毁方法,则将执行这个方法
可以将Bean生命周期内的方法归为四类
Bean自身的方法:如调用Bean构造函数实例化Bean、调用Setter方法设置属性值、通过<bean>的init-method和destory-method所指定的方法
Bean级生命周期的方法:如BeanNameAware,BeanFactoryAware,InitializationBean和DisposableBean,这些接口方法直接由Bean实现
容器级生命周期接口方法: 上图中带* 有InstantiationAwareBeanPostProcessor 和BeanPostProcessor这两个接口实现,一般称他们的实现类为后处理器类,处理器接口一般不由Bean本身实现,他们独立于Bean,
实现类以容器附加装置的形式注册到Spring容器中,当Spring创建任何对象时,这些后处理器类都会发生作用,所以这些后处理器类的影响是全局的。
工厂后处理器接口:包括ApsectJWeavingEnabler,CustomerAutoWireConfigurer,ConfigurationClassPostProcessor 等,也是容器级的,在应用上下文装配配置文件后立即调用。
BeanFactory中Bean生命周期案例
Car.java类代码
package com.example; import org.springframework.beans.BeansException; import org.springframework.beans.factory.*; public class Car implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean { private String brand; private String color; private int maxSpeed; private BeanFactory beanFactory; private String beanName; public Car() { System.out.println("调用Car的构造方法!!"); } public void setBrand(String brand) { this.brand = brand; System.out.println("调用SetBrand()设置属性"); } public void setColor(String color) { this.color = color; System.out.println("调用SetColor()设置属性"); } public void setMaxSpeed(int maxSpeed) { this.maxSpeed = maxSpeed; System.out.println("调用SetMaxSpeed()设置属性"); } public int getMaxSpeed() { return maxSpeed; } public String getBrand() { return brand; } public String getColor() { return color; } public void introduce() { System.out.println("牌子:" + this.brand + " 颜色:" + this.color + " 速度:" + this.maxSpeed); } @Override public String toString() { return "牌子:" + this.brand + " 颜色:" + this.color + " 速度:" + this.maxSpeed; } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("调用BeanFactoryAware.setBeanFactory()."); this.beanFactory = beanFactory; } @Override public void setBeanName(String beanName) { System.out.println("调用BeanNameAware.setBeanName()"); this.beanName = beanName; } @Override public void destroy() throws Exception { System.out.println("调用DisposableBean.destory()"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("调用InitializingBean的方法afterPropertiesSet()"); } //通过<bean>的init-method属性所指定的初始化方法 public void myInit() { System.out.println("调用init-method所指定的myInit()方法"); this.maxSpeed = 240; this.brand = "蓝旗"; this.color = "蓝色"; } //通过<bean>的destory-method属性所指定的销毁方法 public void myDestory() { System.out.println("调用destory-method所指定的myDestory()方法"); } }
InstantiationAwareBeanPostProcessorAdapter后处理器适配器的具体子类 MyInstantiationAwareBeanPostProcess。java代码
package com.example; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValues; import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; import java.beans.PropertyDescriptor; public class MyInstantiationAwareBeanPostProcess extends InstantiationAwareBeanPostProcessorAdapter { // 接口方法:在实例化Bean之前调用 @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { //仅对容器中的car Bean处理 if ("car".equals(beanName)) { System.out.println("InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()方法"); } return null; } //接口方法:实例化Bean之后调用 @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if ("car".equals(beanName)) { System.out.println("InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法"); } return true; } // 接口方法:在设置某个属性的时候调用 @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { if ("car".equals(beanName)) { System.out.println("InstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法"); } return pvs; } }
BeanPostProcessor接口的实现类MyBeanPostProcessor.java代码
package com.example; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if ("car".equals(beanName)) { Car car = (Car) bean; if (car.getColor() == null) { System.out.println("调用BeanPostProcessor.postProcessBeforeInitialization()方法"); car.setColor("red"); } } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if ("car".equals(beanName)) { Car car = (Car) bean; if (car.getMaxSpeed() > 120) { car.setMaxSpeed(120); System.out.println("调用MyBeanPostProcessor的postProcessAfterInitialization()方法"); } } return bean; } }
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-4.0.xsd"> <bean init-method="myInit" destroy-method="myDestory" id="car" class="com.example.Car" p:brand="红旗CA72" p:maxSpeed="200" /> </beans>
BeanLifeCycle.java代码
package com.example; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; public class BeanLifeCycle { private static void LifyCycleBeanFactory() { Resource resource = new ClassPathResource("com/example/beanfactory/beans.xml"); BeanFactory beanFactory = new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((DefaultListableBeanFactory) beanFactory); reader.loadBeanDefinitions(resource); ((ConfigurableBeanFactory) beanFactory).addBeanPostProcessor(new MyBeanPostProcessor()); ((ConfigurableBeanFactory) beanFactory).addBeanPostProcessor(new MyInstantiationAwareBeanPostProcess()); Car car1 = (Car) beanFactory.getBean("car"); car1.introduce(); car1.setColor("红色"); Car car2 = (Car) beanFactory.getBean("car"); System.out.println("car1==car2:" + (car1 == car2)); ((DefaultListableBeanFactory) beanFactory).destroySingletons(); } public static void main(String args[]) { LifyCycleBeanFactory(); } }
最终运行结果
InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()方法 调用Car的构造方法!! InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法 InstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法 调用SetBrand()设置属性 调用SetMaxSpeed()设置属性 调用BeanNameAware.setBeanName() 调用BeanFactoryAware.setBeanFactory(). 调用BeanPostProcessor.postProcessBeforeInitialization()方法 调用SetColor()设置属性 调用InitializingBean的方法afterPropertiesSet() 调用init-method所指定的myInit()方法 调用SetMaxSpeed()设置属性 调用MyBeanPostProcessor的postProcessAfterInitialization()方法 牌子:蓝旗 颜色:蓝色 速度:120 调用SetColor()设置属性 car1==car2:true 调用DisposableBean.destory() 调用destory-method所指定的myDestory()方法
ApplicationContext中的Bean生命周期类似于BeanFactory 不同的是如果Bean实现了org.springframework.context.ApplicationContextAware接口,则会增加一个调用该接口方法setApplicationContext()的步骤如图
以ApplicationContext实现上述一样的功能
工厂后处理器 MyBeanFactoryPostProcessor.java代码
package com.example; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { // 修改配置文件中car 的属性brand初始值为 奇瑞QQ BeanDefinition definition = beanFactory.getBeanDefinition("car"); definition.getPropertyValues().addPropertyValue("brand", "奇瑞QQ"); System.out.println("调用BeanFactoryPostProcessor的postProcessBeanFactory方法"); } }
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-4.0.xsd"> <bean init-method="myInit" destroy-method="myDestory" id="car" class="com.example.Car" p:brand="红旗CA72" p:maxSpeed="200" /> <bean id="myBeanFactoryPostProcessor" class="com.example.MyBeanFactoryPostProcessor"/> <bean id="myInstantionAwareBeanPostProcessor" class="com.example.MyInstantiationAwareBeanPostProcess"/> <bean id="beanPostProcessor" class="com.example.MyBeanPostProcessor"/> </beans>