Spring(九):Bean的生命周期

star2017 1年前 ⋅ 404 阅读

  Spring Bean的生命周期由多个特定的生命队段组成,可以从两个层面来定义Bean的生命周期。第一层是Bean的作用范围;第二层是实例化Bean所经历的一系列阶段。

BeanFactory中Bean 的生命周期

BeanFactoryBean的初始化并不是在启动IoC容器时,是在被第一次调用的时候。BeanFactory对于单例(默认singleton)的Bean会进行缓存,第二次用时直接取。
SpringDefaultSingletonBeanRegistry类中提供了一个用于缓存单例Bean的缓存器,是一个用HashMap实现的缓存器,单例的BeanbeanName为键保存这在这个HashMap中。
BeanFactory-bean-lifeCycle

ApplicationContext中Bean 的生命周期

ApplicationContext则在初始化应用上下文时就实例化所有单例的Bean。如果设置了lazy-init=”true”后,则执行的是懒加载策略,IoC容器启动就不会马上实例化,而是在被调用时实例化。

  1. Bean在应用上下文中的生命周期与在BeanFactory中的生命周期相似,不同的是,如果Bean实现了org.springframework.context.ApplicationContextAware接口,则会增加一个调用该接口方法setApplicationContext()的步骤。
  2. 如果在配置文件(bean.xml)声明了工厂后处理器接口BeanFactoryPostProcessor的实现类,则应用在上下文装载配置文件之后,初始化Bean实例之前将调用postProcessBeanFactory()方法对配置信息进行后处理。工厂后处理器是容器级的,只在应用上下文初始化时调用一次,其目的是完成一些配置文件的加工处理工作。
  3. 另一个不同是ApplicationContext会利用反射机制自动识别出配置文件中定义的BeanPostProcessor,InstantiationAwareBeanPostProcessor,BeanFactoryPostProcessor,并自动将它们注册到应用上下文中;而BeanFactory需要在代码中手工调用addBeanPostProcessor()方法进行注册。
    这些是在应用开发中普遍使用ApplicationContext,而很少使用BeanFactory的原因之一。
  4. ApplicationContext中,只需要配置文件中定义工厂后处理器和Bean后处理器,它们就会按预期的方式运行。
    ApplicationConetxt-bean-lifeCycle

示例代码

BeanFactory

  1. Bean
    实现BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean接口

     package com.smart.beanfactory;
     import org.springframework.beans.BeansException;
     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.context.ApplicationContext;
    
     //管理Bean生命周期的4个接口
     public class Car implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean {
         private String brand;
         private String color;
         private int maxSpeed;
         private String name;
         private BeanFactory beanFactory;
         private String beanName;
    
         public Car() {
             System.out.println("调用Car()构造函数。");
         }
    
         public String getBrand() {
             return brand;
         }
    
         public void setBrand(String brand) {
             System.out.println("调用setBrand()设置属性。");
             this.brand = brand;
         }
    
         public String getColor() {
             return 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("introduce:"+this.toString());
         }
    
         public String toString() {
             return "brand:" + brand + "/color:" + color + "/maxSpeed:"+ maxSpeed;
         }
    
         // BeanFactoryAware接口方法
         public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
             System.out.println("调用BeanFactoryAware.setBeanFactory()。");
             this.beanFactory = beanFactory;
         }
    
         // BeanNameAware接口方法
         public void setBeanName(String beanName) {
             System.out.println("调用BeanNameAware.setBeanName()。");
             this.beanName = beanName;
         }
    
         // InitializingBean接口方法
         public void afterPropertiesSet() throws Exception {
             System.out.println("调用InitializingBean.afterPropertiesSet()。");
         }
    
         // DisposableBean接口方法
         public void destroy() throws Exception {
             System.out.println("调用DisposableBean.destory()。");
         }
    
         //通过<bean>的init-method属性指定初始化方法
         public void myInit() {        
             System.out.println("调用myInit(),将maxSpeed设置为240。");
             this.maxSpeed = 240;
         }
         //通过<bean>的destroy-method属性指定销毁的方法
         public void myDestory() {
             System.out.println("调用myDestroy()。");
         }
    
         public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
             System.out.println("调用setApplicationContext方法");
         }
     }
    
  2. MyBeanPostProcessor

     package com.smart.beanfactory;
    
     import org.springframework.beans.BeansException;
     import org.springframework.beans.factory.config.BeanPostProcessor;
    
     import com.smart.beanfactory.Car;
    
     public class MyBeanPostProcessor implements BeanPostProcessor{
    
         public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {        
             if(beanName.equals("car")){
                 Car car = (Car)bean;
                 if(car.getMaxSpeed() >= 200){
                     System.out.println("调用MyBeanPostProcessor.postProcessAfterInitialization(),将maxSpeed调整为200。");
                     car.setMaxSpeed(200);
                 }
             }
             return bean;
    
         }
    
         public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {        
             if(beanName.equals("car")){
                 Car car = (Car)bean;
                 if(car.getColor() == null){
                     System.out.println("调用MyBeanPostProcessor.postProcessBeforeInitialization(),color为空,设置为默认黑色。");
                     car.setColor("黑色");
                 }
             }
             return bean;
         }
     }
    
  3. MyInstantiationAwareBeanPostProcessor

     ``` java
     package com.smart.beanfactory;
    
     import java.beans.PropertyDescriptor;
    
     import org.springframework.beans.BeansException;
     import org.springframework.beans.PropertyValues;
     import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
    
     public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter{
    
         //在实例化之前调用
         public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
             if("car".equals(beanName)){
                 System.out.println("MyInstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation");            
             }        
             return null;
         }
         //在实例化后调用
         public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
             if("car".equals(beanName)){
             System.out.println("InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation");
             }
             return true;
         }
         //接口方法:在调置某个属性时调用
         public PropertyValues postProcessPropertyValues(
                 PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
                 throws BeansException {
             if("car".equals(beanName)){
                System.out.println("InstantiationAwareBeanPostProcessor.postProcessPropertyValues");
             }
             return pvs;
         }
    
         public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
             return bean;
         }
    
         public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
             return bean;
         }
     }
    
     ```
    
  4. MainBeanFactory

     package com.smart.beanfactory;
    
     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 MainBeanFactory {
    
         private static void LifeCycleInBeanFactory(){
    
            //①下面两句装载配置文件并启动容器
            Resource res = new ClassPathResource("com/smart/beanfactory/beans.xml");
    
            BeanFactory bf= new DefaultListableBeanFactory();
            XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((DefaultListableBeanFactory)bf);
            reader.loadBeanDefinitions(res);
    
            //②向容器中注册MyBeanPostProcessor后处理器
            ((ConfigurableBeanFactory)bf).addBeanPostProcessor(new MyBeanPostProcessor());
    
            //③向容器中注册MyInstantiationAwareBeanPostProcessor后处理器
            ((ConfigurableBeanFactory)bf).addBeanPostProcessor(
                    new MyInstantiationAwareBeanPostProcessor());
            //④第一次从容器中获取car,将触发容器实例化该Bean,这将引发Bean生命周期方法的调用。
            Car car1 = (Car)bf.getBean("car");
            car1.introduce();
            car1.setColor("红色");
    
            //⑤第二次从容器中获取car,直接从缓存池中获取
            Car car2 = (Car)bf.getBean("car");
    
            //⑥查看car1和car2是否指向同一引用
            System.out.println("car1==car2:"+(car1==car2));
            //⑦关闭容器
            ((DefaultListableBeanFactory)bf).destroySingletons();
    
         }
         public static void main(String[] args) {
             LifeCycleInBeanFactory();
         }
     }
    
  5. bean.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 id="car" class="com.smart.beanfactory.Car"
               init-method="myInit"
               destroy-method="myDestory"
               p:brand="红旗CA72"
               p:maxSpeed="200"/>
    
     </beans>
    
  6. 执行结果

     MyInstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
     调用Car()构造函数。
     InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
     InstantiationAwareBeanPostProcessor.postProcessPropertyValues
     调用setBrand()设置属性。
     调用BeanNameAware.setBeanName()。
     调用BeanFactoryAware.setBeanFactory()。
     调用MyBeanPostProcessor.postProcessBeforeInitialization(),color为空,设置为默认黑色。
     调用InitializingBean.afterPropertiesSet()。
     调用myInit(),将maxSpeed设置为240。
     调用MyBeanPostProcessor.postProcessAfterInitialization(),将maxSpeed调整为200。
     introduce:brand:红旗CA72/color:黑色/maxSpeed:200
     car1==car2:true
     调用DisposableBean.destory()。
     调用myDestroy()。
    

ApplicationContext

  1. Bean
    实现BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean, ApplicationContextAware接口。

     package com.smart.context;
    
     import org.springframework.beans.BeansException;
     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.context.ApplicationContext;
     import org.springframework.context.ApplicationContextAware;
    
     //管理Bean生命周期的4个接口
     public class Car implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean, ApplicationContextAware {
         private String brand;
         private String color;
         private int maxSpeed;
         private String name;
         private BeanFactory beanFactory;
         private String beanName;
    
         public Car() {
             System.out.println("调用Car()构造函数。");
         }
    
         public String getBrand() {
             return brand;
         }
    
         public void setBrand(String brand) {
             System.out.println("调用setBrand()设置属性。");
             this.brand = brand;
         }
    
         public String getColor() {
             return 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("introduce:"+this.toString());
         }
    
         public String toString() {
             return "brand:" + brand + "/color:" + color + "/maxSpeed:"+ maxSpeed;
         }
    
         // BeanFactoryAware接口方法
         public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
             System.out.println("调用BeanFactoryAware.setBeanFactory()。");
             this.beanFactory = beanFactory;
         }
    
         // BeanNameAware接口方法
         public void setBeanName(String beanName) {
             System.out.println("调用BeanNameAware.setBeanName()。");
             this.beanName = beanName;
         }
    
         // InitializingBean接口方法
         public void afterPropertiesSet() throws Exception {
             System.out.println("调用InitializingBean.afterPropertiesSet()。");
         }
    
         // DisposableBean接口方法
         public void destroy() throws Exception {
             System.out.println("调用DisposableBean.destory()。");
         }
    
         //通过<bean>的init-method属性指定初始化方法
         public void myInit() {        
             System.out.println("调用myInit(),将maxSpeed设置为240。");
             this.maxSpeed = 240;
         }
         //通过<bean>的destroy-method属性指定销毁的方法
         public void myDestory() {
             System.out.println("调用myDestroy()。");
         }
    
         public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
             System.out.println("调用setApplicationContext方法");
         }
    
     }
    
  2. MyBeanFactoryPostProcessor

     package com.smart.context;
    
     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{
    
         public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException {
             BeanDefinition bd = bf.getBeanDefinition("car");
             bd.getPropertyValues().addPropertyValue("brand", "奇瑞QQ");
             System.out.println("调用MyBeanFactoryPostProcessor.postProcessBeanFactory()!");
         }
     }
    
  3. MyBeanPostProcessor

     package com.smart.context;
    
     import org.springframework.beans.BeansException;
     import org.springframework.beans.factory.config.BeanPostProcessor;
    
     public class MyBeanPostProcessor implements BeanPostProcessor{
    
         public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {        
             if(beanName.equals("car")){
                 Car car = (Car)bean;
                 if(car.getColor() == null){
                     System.out.println("调用MyBeanPostProcessor.postProcessBeforeInitialization(),color为空,设置为默认黑色。");
                     car.setColor("黑色");
                 }
             }
             return bean;
         }
         public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {        
             if(beanName.equals("car")){
                 Car car = (Car)bean;
                 if(car.getMaxSpeed() >= 200){
                     System.out.println("调用MyBeanPostProcessor.postProcessAfterInitialization(),将maxSpeed调整为200。");
                     car.setMaxSpeed(200);
                 }
             }
             return bean;
         }
     }
    
  4. MainApplicationContext

     package com.smart.context;
    
     import org.springframework.context.support.AbstractApplicationContext;
     import org.springframework.context.support.ClassPathXmlApplicationContext;
    
     public class MainApplicationContext {
    
          public static void main(String[] args) {
             AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("com/smart/context/bean.xml");
             Car car =ctx.getBean("car",Car.class);
             Car car1 =ctx.getBean("car",Car.class);
             System.out.println("car == car1 : " + (car == car1));
             ctx.close();
         }
     }
    
  5. bean.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 id="car" class="com.smart.context.Car" init-method="myInit" destroy-method="myDestory"
              p:brand="红旗CA72"
              p:maxSpeed="200"/>
        <bean id="myBeanPostProcessor" class="com.smart.context.MyBeanPostProcessor"></bean>     
        <bean id="myBeanFactoryPostProcessor" class="com.smart.context.MyBeanFactoryPostProcessor"></bean>     
     </beans>
    
  6. 执行结果

     调用MyBeanFactoryPostProcessor.postProcessBeanFactory()!
     调用Car()构造函数。
     调用setBrand()设置属性。
     调用BeanNameAware.setBeanName()。
     调用BeanFactoryAware.setBeanFactory()。
     调用setApplicationContext方法
     调用MyBeanPostProcessor.postProcessBeforeInitialization(),color为空,设置为默认黑色。
     调用InitializingBean.afterPropertiesSet()。
     调用myInit(),将maxSpeed设置为240。
     调用MyBeanPostProcessor.postProcessAfterInitialization(),将maxSpeed调整为200。
     car == car1 : true
    
     三月 19, 2018 12:13:40 上午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
     信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@71be98f5: startup date [Mon Mar 19 00:13:39 CST 2018]; root of context hierarchy
    
     调用DisposableBean.destory()。
     调用myDestroy()。
    

代码GitHub

验证代码GitHub库:SpringBeanLifecycle
SpringBeanLifecycle

更多内容请访问:IT源点

相关文章推荐

全部评论: 0

    我有话说: