首页 > 代码库 > 5.Bean的生命周期

5.Bean的生命周期

1. Bean 的生命周期:

1). Spring IOC 容器可以管理 Bean 的生命周期, Spring 允许在 Bean 生命周期的特定点执行定制的任务.

2). Spring IOC 容器对 Bean 的生命周期进行管理的过程:

     <bean id="person" class="com.atguigu.spring.lifecycle.Person"
          init-method="init"
          destroy-method="destroy">
          <property name="name" value=http://www.mamicode.com/"abcd">
     </bean>

     ①. 通过构造器或工厂方法创建 Bean 实例:调用构造器
     ②. 为 Bean 的属性设置值和对其他 Bean 的引用:调用 setter
     ③. 将 Bean 实例传递给 Bean 后置处理器的 postProcessBeforeInitialization 方法
     ④. 调用 Bean 的初始化方法:init-method
     ⑤. 将 Bean 实例传递给 Bean 后置处理器的 postProcessAfterInitialization方法
     ⑥. Bean 可以使用了
     ⑦. 当容器关闭时, 调用 Bean 的销毁方法:destroy-method

3). Bean 的后置处理器了解):Spring 提供的特殊的 Bean

     ①. Bean 后置处理器允许在调用初始化方法(即:bean 节点 init-method 属性对应的方法的前后)前后对 Bean 进行额外的处理.
     ②. Bean 后置处理器对 IOC 容器里的所有 Bean 实例逐一处理, 而非单一实例. 其典型应用是: 检查 Bean 属性的正确性或根据特定的标准更改 Bean 的属性.
     ③. 对Bean 后置处理器而言, 需要实现  BeanPostProcessor  接口

     public class PersonPostProcessor implementsBeanPostProcessor {
    
          /**
          * arg0:IOC 容器中 bean 的实例
          * arg1:IOC 容器中该 bean 的名字

          */
          @Override
          public ObjectpostProcessAfterInitialization(Object arg0, String arg1)
                    throws BeansException {
               if(arg0 instanceof Person){
                    System.out.println("postProcessAfterInitialization");
                    Person person = (Person) arg0;
              
                    String name = person.getName();
                    if(!name.equals("AAAA")){
                         System.out.println("name 值必须为 AAAA!");
                         person.setName("AAAA");
                    }
               }
         
               return arg0;
          }

          @Override
          public ObjectpostProcessBeforeInitialization(Object arg0, String arg1)
                    throws BeansException {
               System.out.println("postProcessBeforeInitialization");
               return arg0;
          }

     }

     ④. Bean 后置处理器需要在 IOC 容器中进行配置,但不需要指定 id 属性, Spring IOC 容器会自动的识别这是个 Bean 后置处理器,自动的使用它。

     <bean class="com.atguigu.spring.lifecycle.PersonPostProcessor"/>



2. 使用工厂方法配置 bean(了解

1). 使用静态工厂方法来配置 bean

①. 静态工厂方法:直接调用某一个类的静态方法即可返回对应类的一个实例

     public class StaticCarFactory {
    
          private static Map<String, Car> cars = new HashMap<String, Car>();
    
          static{
               cars.put("ford", new Car("ford", "ChangAn", 200000, 200));
               cars.put("mazda", new Car("Mazda", "ChangAn", 210000, 210));
          }

          public static Car get(String brand){
               return cars.get(brand);
          }
    
     }

②. 配置:

     <bean id="car3" class="com.atguigu.spring.factory.StaticCarFactory"
          factory-method="get">
          <constructor-argvalue=http://www.mamicode.com/"ford"></constructor-arg>    
     </bean>

     注意:
     I.   class 指向的是静态工厂类;
     II.  factory-method 配置的是静态工厂方法中的方法;
     III. 若静态方法需要传入参数,则使用 <constructor-arg value=http://www.mamicode.com/"ford"> 方式传入参数


2). 使用实例工厂方法来配置 bean

     public class InstanceCarFactory {
    
          private Map<String, Car> cars = new HashMap<String, Car>();
    
          public InstanceCarFactory() {
               cars.put("ford", new Car("ford", "ChangAn", 200000, 200));
               cars.put("mazda", new Car("Mazda", "ChangAn", 210000, 210));
          }
    
          public Car get(String brand){
               return cars.get(brand);
          }
    
     }

     <!-- 1. 配置实例工厂本身的 bean -->
     <bean id="carFactory" class="com.atguigu.spring.factory.InstanceCarFactory"></bean>

     <!-- 2.增加实例工厂方法配置 bean -->
     <bean id="car4" factory-bean="carFactory" factory-method="get">
          <constructor-arg value=http://www.mamicode.com/"mazda">
     </bean>



3. 通过 FactoryBean 来配置 Bean 的实例(关注)

     1). 实现 FactoryBean 接口:

     public class CarFactoryBean implements FactoryBean<Car> {

          //返回的 Bean 的实例
          @Override
          public Car getObject() throws Exception {
               return new Car("BMW", "HUACHEN", 300000, 300);
          }

          //返回的 Bean 的类型
          @Override
          public Class<?> getObjectType() {
               return Car.class;
          }

          //返回的 Bean 是否为单例
          @Override
          public boolean isSingleton() {
               return true;
          }

     }

2). 在 IOC 容器中配置 Bean:class 属性指向 FactoryBean 接口的实现类,实际返回的是 FactoryBean 的 getObject() 方法的 Bean

     <bean id="car5"  class="com.atguigu.spring.factorybean.CarFactoryBean"></bean>

3). 使用

     Car car = (Car) ctx.getBean("car5");



5.Bean的生命周期