spring bean 的生命週期java
spring BeanFactory及ApplicationContext在讀取配置文件後、實例化bean先後、設置bean的屬性先後這些點均可以經過實現接口添加咱們本身的邏輯spring
spring BeanFactory中Bean的生命週期緩存
demo1 框架
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.3.16.RELEASE</version> </dependency> </dependencies>
import org.springframework.beans.BeansException; import org.springframework.beans.factory.*; /** * BeanFactoryAware 覺察到 * InitializingBean 初始化 * Disposable 一次性的,可任意處理的; 用後就拋棄的 * * BeanFactoryAware、BeanNameAware、InitializingBean、DisposableBean都是Bean級的生命週期控制接口 */ public class Car implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean { // 品牌 private String brand; // 顏色 private String color; // 最快速度 private int maxSpeed; public Car() { System.out.println("構造方法執行"); } public void setBrand(String brand) { System.out.println("setBrand方法執行"); this.brand = brand; } public String getColor() { return this.color; } public void setColor(String color) { this.color = color; } public int getMaxSpeed() { return maxSpeed; } public void setMaxSpeed(int maxSpeed) { this.maxSpeed = maxSpeed; } public void introduce() { System.out.println("brand:" + brand + ";color:" + color + ";maxSpeed:" + maxSpeed); } private BeanFactory beanFactory; @Override // 實現BeanFactoryAware須要重寫的惟一方法 public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("調用BeanFactoryAware接口定義的setBeanFactory方法"); this.beanFactory = beanFactory; } private String beanName; @Override // 實現BeanNameAware須要重寫的惟一方法 public void setBeanName(String beanName) { System.out.println("調用BeanNameAware接口定義的setBeanName方法"); this.beanName = beanName; } @Override // 實現InitializingBean須要重寫的惟一方法 public void afterPropertiesSet() throws Exception { System.out.println("調用InitializingBean接口定義的afterPropertiesSet方法"); } @Override // 實現DisposableBean須要重寫的惟一方法 public void destroy() throws Exception { System.out.println("調用DisposableBean接口定義的destroy方法"); } // 經過<bean>的init-method屬性指定的初始化方法 public void myInit() { System.out.println("調用init-method指定的myInit方法,將maxSpeed設置爲240"); this.maxSpeed = 240; } // 經過<bean>的destroy-method屬性指定的銷燬方法 public void myDestroy() { System.out.println("調用destroy-method指定的myDestroy方法"); } }
import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValues; import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; import java.beans.PropertyDescriptor; public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { /** * 在實例化Bean前調用,僅對容器中的car Bean處理 * * 父類實現了接口 SmartInstantiationAwareBeanPostProcessor, * SmartInstantiationAwareBeanPostProcessor 又繼承了接口 InstantiationAwareBeanPostProcessor * InstantiationAwareBeanPostProcessor 又繼承了 BeanPostProcessor * 有方法postProcessBeforeInstantiation */ public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if ("car".equals(beanName)) { System.out.println("InstantiationAwareBeanPostProcessor 接口的 postProcessBeforeInstantiation 方法執行"); } return null; } /** * 在實例化Bean後調用,僅對容器中的car Bean處理 * * 同上,InstantiationAwareBeanPostProcessor 有方法 postProcessAfterInstantiation */ public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if ("car".equals(beanName)) { System.out.println("InstantiationAwareBeanPostProcessor 接口的 postProcessAfterInstantiation 方法執行"); } return true; } /** * 在設置某個屬性時調用,僅對car Bean的品牌屬性值進行處理,還能夠經過pds入參進行過濾 * * 同上,InstantiationAwareBeanPostProcessor 有方法 postProcessPropertyValues */ public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { if ("car".equals(beanName)) { System.out.println("InstantiationAwareBeanPostProcessor 接口的 postProcessPropertyValues 方法執行"); } return pvs; } }
import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; /** * processor 加工,處理 * BeanPostProcessor後處理器在spring框架中佔有重要的地位,這是容器對Bean進行後續加工處理的切入點; * spring提供的動態代理、AOP都是經過BeanPostProcessor實現的 */ public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("car")) { Car car = (Car)bean; if (car.getColor() == null) { System.out.println("調用接口BeanPostProcessor的postProcessBeforeInitialization方法," + "color爲空,設置爲默認黑色"); car.setColor("黑色"); } } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("car")) { Car car = (Car)bean; if (car.getMaxSpeed() >= 200) { System.out.println("調用接口BeanPostProcessor的postProcessAfterInitialization方法," + "將maxSpeed調整爲200"); car.setMaxSpeed(200); } } return bean; } }
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="car" class="Car" init-method="myInit" destroy-method="myDestroy" p:brand="寶馬373" p:maxSpeed="220"/> </beans>
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; /** * 測試類 */ public class BeanLifeCycle { public static void main(String[] args) { lifeCycleBeanFactory(); } private static void lifeCycleBeanFactory() { // 裝載配置文件 ClassPathResource resource = new ClassPathResource("my.xml"); // 啓動容器 DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((DefaultListableBeanFactory) beanFactory); reader.loadBeanDefinitions(resource); // 向容器中註冊MyBeanPostProcessor後處理器 ((ConfigurableBeanFactory)beanFactory).addBeanPostProcessor(new MyBeanPostProcessor()); // 向容器中註冊MyInstantiationAwareBeanPostProcessor後處理器 ((ConfigurableBeanFactory)beanFactory).addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor()); // 第一次從容器中獲取car,將觸發容器實例化這個Bean,這將引起Bean生命週期方法的調用 Car car1 = (Car)beanFactory.getBean("car"); car1.introduce(); car1.setColor("紅色"); // 第二次從容器中獲取car,直接從緩存池中獲取 Car car2 = (Car) beanFactory.getBean("car"); // 查看car1和car2是否指向同一引用 System.out.println("car1==car2:" + (car1 == car2)); ((DefaultListableBeanFactory)beanFactory).destroySingletons(); } }
1、InstantiationAwareBeanPostProcessor 接口的 postProcessBeforeInstantiation 方法執行 構造方法執行 2、InstantiationAwareBeanPostProcessor 接口的 postProcessAfterInstantiation 方法執行 3、InstantiationAwareBeanPostProcessor 接口的 postProcessPropertyValues 方法執行 setBrand方法執行 4、調用BeanNameAware接口定義的setBeanName方法 5、調用BeanFactoryAware接口定義的setBeanFactory方法 6、調用接口BeanPostProcessor的postProcessBeforeInitialization方法,color爲空,設置爲默認黑色 7、調用InitializingBean接口定義的afterPropertiesSet方法 八、調用init-method指定的myInit方法,將maxSpeed設置爲240 9、調用接口BeanPostProcessor的postProcessAfterInitialization方法,將maxSpeed調整爲200 brand:寶馬373;color:黑色;maxSpeed:200 car1==car2:true 10、調用DisposableBean接口定義的destroy方法 十一、調用destroy-method指定的myDestroy方法 輸出分析: 在一個bean實例化之間以後,調用一、2。 1的方法入參是Class<?> beanClass, String beanName,分別對應bean的class和id 2的方法入參是Object bean, String beanName,分別對應實例化好的bean和bean的id 在屬性填充前,調用3。 3的方法入參是PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName pvs裏封裝着屬性值,pds裏封裝着屬性名,bean是實例化後的bean,beanName是bean的id 屬性填充後,調用四、5。 4的方法入參是String beanName,能夠把beanName也就是bean的id緩存起來,保存爲一個成員變量 5的方法入參是BeanFactory beanFactory,能夠把beanFactory緩存起來,保存爲一個成員變量 在bean初始化以前以後調用六、9,這是BeanPostProcessor的方法,能夠修改屬性值,能夠添加AOP 7、8是初始化方法 十、11是銷燬方法
其中的BeanPostProcessor接口很是重要,spring的動態代理、AOP都是經過實現這個接口而爲bean添加行爲的ide
spring ApplicationContext中Bean的生命週期post
Spring Bean在ApplicationContext和BeanFactory中的生命週期相似。測試
不一樣的是,若是Bean實現了org.springframework.context.ApplicationContextAware接口,會增長一個調用該接口方法setApplicationContext()的步驟。ui
而且多了BeanFactoryPostProcessor接口,若是實現了該接口,ApplicationContext在裝載配置文件以後、實例化Bean以前將調用該實現類的方法,對配置信息進行加工處理。Spring框架提供了多個工廠後處理器,如CustomEditorConfigurer、PopertyPlaceholderConfigurer等。工廠後處理器是容器級的,僅在ApplicationContext初始化時調用一次。this
ApplicationContext在啓動時,將首先爲配置文件中的每一個<bean>生成一個BeanDefinition對象,BeanDefinition是<bean>在Spring容器中的內部表示。當配置文件中全部的<bean>都被解析爲BeanDefinition時,ApplicationContext將調用工廠後處理器的方法,因些,咱們有機會經過程序的方式調整Bean的配置信息。spa
ApplicationContext和BeanFactory的一個最大的不一樣之處在於,前者會利用Java反射機制自動識別出配置文件中定義的BeanPostProcessor、InstantiationAwareBeanPostProcessor及BeanFactoryPostProcessor,並自動將它們註冊到ApplicatContext中(在ApplicatContext中,只需在配置文件中經過<bean>定義工廠後處理器和Bean後處理器,它們就會按預期的方式運行);然後者須要在代碼中手工調用addBeanProcessor()方法進行註冊。
demo2——BeanFactoryPostProcessor
還使用demo1那個例子的代碼,添加了MyBeanFactoryPostProcessor的實現、修改了my.xml、修改了測試類
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 // 實現BeanFactoryPostProcessor須要重寫的惟一方法 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { BeanDefinition beanDefinition = beanFactory.getBeanDefinition("car"); beanDefinition.getPropertyValues().addPropertyValue("brand", "吉利博瑞"); System.out.println("調用BeanFactoryPostProcessor的postProcessBeanFactory方法"); } }
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="car" class="Car" init-method="myInit" destroy-method="myDestroy" p:brand="寶馬373" p:maxSpeed="220"/> <bean class="MyBeanPostProcessor"/> <bean class="MyInstantiationAwareBeanPostProcessor"/> <bean class="MyBeanFactoryPostProcessor"/> </beans>
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * 測試類 */ public class BeanLifeCycle { public static void main(String[] args) { lifeCycleBeanFactory(); } private static void lifeCycleBeanFactory() { ApplicationContext context = new ClassPathXmlApplicationContext("classpath:my.xml"); Car car1 = (Car)context.getBean("car"); car1.introduce(); car1.setColor("紅色"); // 第二次從容器中獲取car,直接從緩存池中獲取 Car car2 = (Car) context.getBean("car"); // 查看car1和car2是否指向同一引用 System.out.println("car1==car2:" + (car1 == car2)); ((ClassPathXmlApplicationContext)context).destroy(); } }
demo3——BeanFactoryPostProcessor
經過程序的方式調整Bean的配置信息
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.3.16.RELEASE</version> </dependency>
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Driver { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("my.xml"); Boss boss1 = context.getBean("boss1", Boss.class); Boss boss2 = context.getBean("boss2", Boss.class); System.out.println(boss1); System.out.println(boss2); } } class Boss { private Car car; public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } } class Car { }
import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.DefaultListableBeanFactory; /** * BeanPostProcessor * Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; * Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; * * BeanFactoryPostProcessor * void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; * * BeanPostProcessor和BeanFactoryPostProcessor是兩個不一樣的接口: * BeanPostProcessor是在Bean實例化後、屬性設置後執行,是Spring AOP 的賴以實現的基礎; * BeanFactoryPostProcessor是WebApplicationContext讀取配置文件後,尚未初始化任何實例時運行, * 能夠用來修改配置文件 * */ public class UserServiceFactoryBean implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException { // 把ConfigurableListableBeanFactory轉化爲DefaultListableBeanFactory DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) bf; // 經過BeanDefinitionBuilder建立bean定義 BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(Boss.class); // 設置屬性userDao,此屬性引用已經定義的bean:car beanDefinitionBuilder.addPropertyReference("car", "car"); // 註冊bean定義 beanFactory.registerBeanDefinition("boss1", beanDefinitionBuilder.getRawBeanDefinition()); // 直接註冊一個bean實例 beanFactory.registerSingleton("boss2", new Boss()); } }
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="car" class="Car"/> <bean class="UserServiceFactoryBean"/> </beans>