• (一)IOC 容器:【8】Bean组件的生命周期


     一、Bean 的生命周期

        Bean的生命周期是指:bean创建 ---  初始化 --- 销毁的过程
        Spring中是由 IOC 容器管理 bean 的生命周期,我们可以自定义初始化和销毁方法,
        容器在 bean 进行到当前生命周期的时候来调用我们自定义初始化方法和销毁方法。
    
    
        1、构造方法(对象创建)
                单实例:在容器启动的时候创建对象;
                多实例:每次获取的时候创建对象;
    
        2、初始化方法
                单实例:对象创建完成,并赋值好,调用初始化方法。
                多实例bean:在创建的时候调用;
    
        3、销毁方法
                单实例:容器关闭的时候,销毁对象;
                多实例:容器不会管理整个bean,在需要的时候负责创建,容器不会调用销毁方法。
    
    
         方式一:指定初始化和销毁方法
                通过 @Bean 指定 init-method 和 destory-method 方法
    
    
         方式二:通过让 Bean 实现 InitializingBean(定义初始化逻辑) 和 DisposableBean(定义销毁逻辑) 这两个接口,
                然后重写其中的方法。
    
         方式三:使用 JSR250规范中的注解
                在方法上使用注解来进行说明。
                @PostConstruct:在 bean创建完成并且属性赋值完成,来执行初始化方法,在方法上
                @PreDestroy:在容器销毁 bean之前通知我们进行清理工作
    
        使用 BeanPostProcessor bean的后置处理器
                postProcessBeforeInitialization:在初始化之前工作
                postProcessAfterInitialization:在初始化之后工作

    二、方式一:@Bean 注解指定方法

      使用 @Bean 注解指定初始化和销毁方法;

      原来是在配置文件的 bean 标签中使用 init-method 和 destory-method 来指定方法。

      现在可以在配置类中通过 @Bean 注解中的 initMethod 和 destoryMethod 来指定方法:

      声明 Car 类:

    public class Car {
    
        public Car() {
            System.out.println("Car  constructor...");
        }
    
        public void init() {
            System.out.println("Car ... init...");
        }
    
        public void destory() {
            System.out.println("Car ... destory...");
        }
    }

      配置类:

    @Configuration
    public class MainConfigOfLifeCycle {
    
        @Bean(initMethod = "init", destroyMethod = "destory")
        public Car getCar() {
            return new Car();
        }
    }

      测试:

        @Test
        public void test01() {
            AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
    
            System.out.println("IOC容器创建完毕");
    
            ioc.close();
        }

      

    三、方式二:实现接口

      通过让 Bean 实现 InitializingBean(定义初始化逻辑) 和 DisposableBean(定义销毁逻辑) 这两个接口,然后重写其中的方法。

      声明 Cat 类:

    public class Cat implements InitializingBean, DisposableBean {
    
        public Cat() {
            System.out.println("cat constructor");
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("cat ... afterPropertiesSet ...");
        }
    
        @Override
        public void destroy() throws Exception {
            System.out.println("cat ... destory ...");
        }
    }

      配置类:

    @Configuration
    public class MainConfigOfLifeCycle {
    
        @Bean
        public Cat getCat() {
            return new Cat();
        }
    }

    四、方式三

      使用 JSR250 规范中的注解,在方法上面使用注解来进行说明:

    @PostConstruct:在 bean创建完成并且属性赋值完成,来执行初始化方法,在方法上
    @PreDestroy:在容器销毁 bean之前通知我们进行清理工作
    

      

      声明 Dog 类:

    public class Dog {
    
        public Dog() {
            System.out.println("Dog constructor");
        }
    
        //对象创建并赋值之后调用
        @PostConstruct
        public void init() {
            System.out.println("Dog....@PostConstruct。。。");
        }
    
        //容器移除对象之前
        @PreDestroy
        public void destory() {
            System.out.println("Dog....@PreDestroy。。。");
        }
    }

      配置类:

    @Configuration
    public class MainConfigOfLifeCycle {
    
        @Bean
        public Dog getDog() {
            return new Dog();
        }
    }

      测试:

    五、方式四:BeanPostProcessor 后置处理器

      使用 BeanPostProcessor  bean的后置处理器

    postProcessBeforeInitialization:在初始化之前工作
    postProcessAfterInitialization:在初始化之后工作
    

     

      定义 Bean 的后置处理器:

    /**
     * 后置处理器:初始化前后进行处理工作
     * 将后置处理器加入到容器中
     */
    public class MyBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("postProcessBeforeInitialization" +  beanName + "=>" + bean);
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("postProcessAfterInitialization" +  beanName + "=>" + bean);
            return bean;
        }
    }

      将后置处理器添加到容器中:

    @Configuration
    public class MainConfigOfLifeCycle {
    
        @Bean
        public Dog getDog() {
            return new Dog();
        }
    
        @Bean
        public MyBeanPostProcessor getMyBeanPostProcessor() {
            return new MyBeanPostProcessor();
        }
    }

      测试:

    六、BeanPostProcessor 原理

      源码 DeBug:【AbstractAutowireCapableBeanFactory】

      流程:

    populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
    initializeBean
    {
        applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
        applyBeanPostProcessorsAfterInitialization(wrappedBean,  beanName);
    }
    

      

      遍历得到容器中所有的 BeanPostProcessor;挨个执行 beforeInitialization,

      一但返回null,跳出for循环,不会执行后面的 BeanPostProcessor.postProcessorsBeforeInitialization

      Spring 底层对 BeanPostProcessor 的使用:

        ① ApplicationContextAwareProcessor:用于向 bean 组件中添加 ioc 容器;

        ② BeanValidationPostProcessor:用于数据的校验工作;

        ③ InitDestroyAnnotationBeanPostProcessor:用于解析 @PostConstruct 和 @PreDestory 注解

        ④ AutowiredAnnotationBeanPostProcessor:解析 @Autowired 注解,来注入其他组件;

        

      Spring 中提供了一系列的 BeanPostProcessor,可以用于给 bean 赋值,注入其他组件,还有的用来解析 @Autowired 注解,解析生命周期注解功能的多样的 BeanPostProcessor。

      

  • 相关阅读:
    (转)Pythonfunctools详解
    (转)这有 73 个例子,彻底掌握 fstring 用法!
    (转)你不一定全知道的四种Python装饰器实现详解
    (转)学习Python,怎能不懂点PEP呢?
    (转)5个案例详解装饰器 | 手把手教你入门Python之四十六
    (转)Python 对象协议
    (转)functools — 函数操作工具箱
    (转)Python 魔术方法指南
    Python 对象协议
    (转)Python timeit模块的使用实践
  • 原文地址:https://www.cnblogs.com/niujifei/p/15549899.html
Copyright © 2020-2023  润新知