• 二、Bean的生命周期


    bean的生命周期:bean的创建---->bean的初始化--->bean的销毁,Bean的生命周期由容器来管理,Coder可以自定义初始化和销毁方法,容器在bean进行到当前生命周期的时候来调用编写的自定义的初始化和销毁方法。

    1、管理生命周期的方式

    1. 指定初始化和销毁方法。

    2. 通过让Bean实现InitializingBean接口(定义初始化),DisposableBean接口(定义销毁)。

    3. 使用JSR250的@PostConstruct和@PreDestroy。

    4. 通过Bean的后置处理器BeanPostProcessor

    2、生命周期的时机:

    • 构造(对象创建):

      • 单实例:在容器启动的时候创建对象

      • 多实例:在每次获取的时候创建

    • 初始化:

      • 对象创建完成,并赋值好,调用出初始化方法

    • 销毁:

      • 单实例容器关闭时销毁

      • 多实例容器不会管理多实例bean的销毁。

    一、指定初始化和销毁方法

      使用initMethod/destoryMethod指定初始化和销毁方法

    @Repository
    public class Person {
        
        public Person() {
            System.out.println("person的无参构造器");
        }
    
        public void initMethod(){
            System.out.println("初始化方法");
        }
    
        public void destoryMethod(){
            System.out.println("销毁方法");
        }
    }
    • 主配置类
    @Configuration
    public class MyConfigOfLifeCycle {
        @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
        @Bean(initMethod = "initMethod",destroyMethod = "destoryMethod")
        public Person person(){
            return new Person();
        }
    }
    • 测试
    public void test08(){
         // 单实例bean,创建IOC容器时就会调用bean的构造器创建单实例bean,同时调用initMethod初始化方法
          //多实例bean,是在获取bean的实例时创建bean,同时调用initMethod初始化方法
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfigOfLifeCycle.class);
            Person perosn = context.getBean("person", Person.class);
             //关闭容器时,调用bean销毁方法
            context.close();
        }

    二、实现InitializingBean和DisposableBean接口

    public class Cat implements InitializingBean, DisposableBean {
    
        public Cat() {
            System.out.println("Cat的无参构造器");
        }
            
          //在属性设置完成之后调用
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("afterPropertiesSet ======= " );
        }
    
        @Override
        public void destroy() throws Exception {
            System.out.println("destroy ======= " );
        }
    }
    • 主配置类
    @Configuration
    public class MyConfigOfLifeCycle {
    
        @Bean
        public Cat cat(){
            return new Cat();
        }
    }
    • 测试
    @Test
        public void test09(){
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfigOfLifeCycle.class);
            Cat cat = context.getBean("cat", Cat.class);
            //关闭容器时,调用bean销毁方法
            context.close();
        }

    三、使用JSR250

    • @PostConstruct:在Bean创建完成并且属性赋值完成,来执行初始化方法

    • @PreDestroy:在容器销毁Bean之前通知我们进行清理工作

    @Component
    public class Student {
       
        public Student() {
            System.out.println("student construct.....");
        }
        //对象创建并且赋值之后
        @PostConstruct
        public void init(){
            System.out.println("init......");
        }
        //容器销毁之前
        @PreDestroy
        public void destory(){
            System.out.println("destory......");
        }
    }
    • 主配置类
    @Configuration
    @ComponentScan(basePackages="com.jdy.bean")
    public class MyConfigOfLifeCycle {
       
    }

    四、Bean的后置处理器

    在Bean初始化前后进行处理工作,针对是IOC容易中每一个Bean。

    • postProcessBeforeInitialization:Bean初始化之前进行处理

    • postProcessAfterInitialization:Bean初始化之后进行处理

      创建后置处理器实现BeanPostProcessor接口

    /**
     * @author Mr.jdy
     * @create 2020-07-11 20:40
     * 后置处理器在初始化前后执行
     *            bean:IOC容器中创建的Bean
     *             beanName:IOC容器中Bean的名字
     * 可以在MyProcessor中打断点查看
     */
    @Component
    public class MyProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println(beanName+"==postProcessBeforeInitialization....");
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println(beanName+"==postProcessAfterInitialization....");
            return bean;
        }
    }
    • 主配置类
    @Configuration
    @ComponentScan(basePackages={"com.jdy.bean","com.jdy.processor"})
    public class MyConfigOfLifeCycle {
    }

    五、BeanPostProcessor原理、

      org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

      遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,一旦返回null,跳出for循环,不会执行后面的BeanPostProcessor。BeanPostProcessor.postProcessAfterInitialization   

    • Spring底层对BeanPostProcessor的使用

        ApplicationContextAware:在组件里面注入IOC容器

    @Component
    public class Pig implements ApplicationContextAware {
    
        private ApplicationContext context;
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.context=applicationContext;
        }
    }
  • 相关阅读:
    美文:人生如果是十分
    收藏若干敏捷开发的博文充电
    推荐 xiaotie 的开源GIS专题文章索引
    影像融合操作的几种途径
    开源版多用户博客系统
    软件的架构与设计模式之模式的种类介绍
    开源摄影测量与遥感处理软件OSSIM简介
    从面向对象到模式再到真正的面向对象
    MapGuide和MapServer的一些资源
    ArcInfo常用命令整理
  • 原文地址:https://www.cnblogs.com/jdy1022/p/13928376.html
Copyright © 2020-2023  润新知