zoukankan      html  css  js  c++  java
  • BeanFactory中Bean的生命周期

    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>
  • 相关阅读:
    BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第15章节--开发SP2013工作流应用程序 总结
    OpenStreetMap初探(一)——了解OpenStreetMap
    企业服务总线架构介绍
    【Stackoverflow好问题】java在,如何推断阵列Array是否包括指定的值
    C和指针 (pointers on C)——第一章:高速启动
    类别sort使用排序
    [Oracle]
    4点,从今天谈用户体验设计经验京东亚马逊购物
    从[java.lang.OutOfMemoryError: Java heap space]恢复
    C++学习笔记32 断言函数
  • 原文地址:https://www.cnblogs.com/09120912zhang/p/7746952.html
Copyright © 2011-2022 走看看