zoukankan      html  css  js  c++  java
  • 4.spriing:Bean的生命周期/工厂方法配置Bean/FactoryBean

    1.Bean的生命周期 

    scope:singleton/prototype

     1)spring容器管理singleton作用的生命周期,spring能够精确知道Bean合适创建,何时初始化完成,以及何时被销毁

    2)spring容器管理prototype作用的生命周期,spring只负责创建,容器实例化之后就交给客户端进行管理,spring容器不会再

      跟踪其生命周期。

    可以借鉴servlet的生命周期“实例化--初始化--接受请求--销毁”

    Spring IOC容器可以管理Bean的生命周期,Spring允许在Bean生命周期的特定点执行特定的任务
    在SpringIOC容器对Bean的生命周期进行管理的过程
    ->通过构造器或者工厂的方法创建Bean实例
    ->为Bean的属性设置值和其他的Bean的引用
    ->调用bean的初始化方法
    ->bea调用使用了
    ->当容器关闭的时候,调用Bean的销毁方法
    在Bean的声明里设置 ini-method destroy-method属性,为Bean指定初始化和销毁的方法

    Car.java

    public class Car {
        private String brand;public void init() {
            System.out.println("init");
        }public void destroy() {
            System.out.println("destroy");
        }

         public void setBrand(String brand) {
          System.out.println("setBrand");
          this.brand = brand;
        }

      //....
    }

    applicationContext.xml

    <bean id="car" class="com.MrChengs8.TheLifeCycle.Car" init-method="init" 
    destroy-method="destroy"> <property name="brand" value="Aodi"></property>
    </bean>

    测试:

            Car car = (Car) ctx.getBean("car");
            System.out.println(car);
            
            //关闭IOc容器
            //ClassPathXmlApplicationContext
            //子接口里面有关闭IOC容器的方法
            ctx.close();
    setBrand
    init Car [brand
    =Aodi] destroy

    先调用构造函数和设置属性,然后再init()

    Bean的后置处理器:

    创建Bean后置处理器:
    Bean后置处理器允许在调用初始化的时候对前后的Bean进行额外的处理
    Bean的后置处理器对IOC容器里的所有的Bean实例逐一处理,而非单一的实例,

    其典型的应用是:检查Bean属性的正确性或者根据特定的标准去修改bean

    对Bean后置处理器而言,更需要实现的是Interface BeanPostProcessor接口,在初始化方法被调用的前后,
    Spring将把每个Bean的实例分别传递给接口以下的两个方法
    ->postProcessAfterInitialization(Object arg0, String arg1)
    ->postProcessBeforeInitialization(Object arg0, String arg1)

    实现并提供两个方法的实现在类中
    Object arg0, String arg1
    arg0:bean的实例本身
    arg1:IOC容器配置的bean的名字
    在IOC容器会自动识别是一个后置处理器

    TheLatterPostprocessor.java

    public class TheLatterPostprocessor implements BeanPostProcessor{
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String arg1) throws BeansException {
            System.out.println("postProcessAfterInitialization__After__::" + arg1 + "---" + bean);
            Car car = new Car();
            car.setBrand("BBBBB");
            return car;
        }
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String arg1) throws BeansException {
            System.out.println("postProcessBeforeInitialization__Before__::" + arg1  + "---" + bean);
            return bean;
        }
    
    }

    applicationContext.xml

    <!--配置Bean的后置处理器 -->
    <bean class="com.MrChengs8.TheLifeCycle.TheLatterPostprocessor"></bean>
    setBrand
    postProcessBeforeInitialization__Before__::car---Car [brand=Aodi]
    init
    postProcessAfterInitialization__After__::car---Car [brand=Aodi]
    setBrand
    Car [brand=BBBBB]
    destroy

    2.工厂方法配置Bean

    1).实例工厂实例化

    实例工厂方法:将对象创建的过程封装到另外一个对象实例方法里,当客户需要请求对象时,只需要简单的调用该实例方法发,不必关心创建的细节
    要声明通过实例工厂方法创建Bean:
    ->在bean的factory-method属性里指定拥有该方法的Bean
    ->在factory-method属性里指定该工厂方法的名称
    ->使用 construtor元素为工厂方法传递参数

    Car.java

    public class Car {
        private String brand;
        private double price;public Car(String brand, double price) {
            super();
            this.brand = brand;
            this.price = price;
        }
      //.....    
    }

    InstanceFactoryMethod.java

    public class InstanceFactoryMethod {
    
        private Map<String, Car> cars = null;
        
        public InstanceFactoryMethod(){
            cars = new HashMap<String, Car>();
            cars.put("aodi", new Car("aodi", 10000));
            cars.put("ford", new Car("ford",20000));
        }
        
        public Car getCar(String name){
            return cars.get(name);
        }
    }

    applicationContext.xml

    <!-- 配置工厂的实例 -->
    <bean id="car1" class="com.MrChengs9.FactoryMethod.InstanceFactoryMethod" ></bean>
    <!-- 通过实例工厂方法来配置bean -->
    <bean id="car2" factory-bean="car1" factory-method="getCar">
        <constructor-arg value="ford"></constructor-arg>
    </bean>

    测试

            Car car2 = (Car) ctx.getBean("car2");
            System.out.println(car2);
    Car [brand=ford, price=20000.0]

    2).静态工厂方法

    利用静态工厂方法可以把bean注入到IOC容器中。在XML文件中配置bean时,要指定class的属性为工厂的类;factory-method属性指定工厂类中
    工厂方法,用于创建bean;constrctor-arg用于给工厂方法传递参数

    StaticFactoryMethod.java

    public class StaticFactoryMethod {
        private static Map<String, Car> cars = new HashMap<String, Car>();
        
        static{
            cars.put("audi", new Car("audi", 1234));
            cars.put("ford", new Car("ford", 4321));
        }
        
        public static Car getCars(String name){
            return cars.get(name);
        }
    }

    applicationContext.xml

    <!-- 静态工厂方法来配置Bean实例,不是配置静态工厂方法实例,而是去配置Bean实例 -->
    <!-- 
    Class属性指向静态工厂方法的全类名
    factory-method:指向静态工厂的名字
    constructor-arg:工厂需要传入canshu,则使用此元素
     -->
    <bean id="car" class="com.MrChengs9.FactoryMethod.StaticFactoryMethod" 
    factory-method="getCars">
        <constructor-arg value="audi"></constructor-arg>
    </bean>
            Car car1 = (Car) ctx.getBean("car");
            System.out.println(car1);
    Car [brand=audi, price=1234.0]

    3.FactoryBean

    FactoryBean是一个接口,要用的话就要实现它。他有三个方法:

      getObject()  //返回bean对象

      getObjectType()  //返回bean的类型

        isSingleton()   //是否单例

    CarFactoryBean.java

    public class CarFactoryBean implements FactoryBean<Car>{
        
        private String brand;
        public void setBrand(String brand) {
            this.brand = brand;
        }
        //返回bean的对象
        @Override
        public Car getObject() throws Exception {
            // TODO Auto-generated method stub
            return new Car(brand,100000);
        }
        //返回bean的类型
        @Override
        public Class<?> getObjectType() {
            // TODO Auto-generated method stub
            return Car.class;
        }
        //返回bean是不是单实例的
        @Override
        public boolean isSingleton() {
            // TODO Auto-generated method stub
            return false;
        }
    }

    Car.java

    public class Car {
        private String brand;
        private double price;public Car(String brand, double price) {
            super();
            this.brand = brand;
            this.price = price;
        }
      //...... }

    applicationContext.xml

        通过FactoryBean来配置Bean的实例
        class:指向FactoryBean的全类名
        property:配置FactoryBean的属性
        但是实际返回的是FactoryBean的getObject()方法
    <bean id="car" class="com.MrChengsa.FactoryBean.CarFactoryBean">
        <property name="brand" value="BMW"></property>
    </bean>
            Car car = (Car) ctx.getBean("car");
            System.out.println(car);
    Car [brand=BMW, price=100000.0]

     但实际返回实例确是 FactoryBean 的 getObject() 方法返回的实例!

  • 相关阅读:
    流的概念(转自本站progor)
    Centos7安装OpenLDAP
    python发送post请求
    小计安装部署滴滴开源kafkamanager工具
    VSCode集成Cmder控制台输入中文乱码
    在win10的pycharm使用wsl中的python进行开发
    《Python数据科学手册》学习笔记及书评
    VSCode小说插件ReadNovel根据内容查找页码
    《TensorFlow实战Google深度学习框架(第二版)》学习笔记及书评
    Cmder启动WSL中的Ubuntu出现复制粘贴异常
  • 原文地址:https://www.cnblogs.com/Mrchengs/p/10087663.html
Copyright © 2011-2022 走看看