美文网首页
springboot之IOC容器Bean声明周期监听

springboot之IOC容器Bean声明周期监听

作者: eliteTyc | 来源:发表于2019-12-17 16:33 被阅读0次

    ioc中bean组件声明周期

    • 创建-初始化-销毁

    • 容器管理组件的声明周期

    • 我们可以自定义初始化和销毁方法,当组件的生命周期到这个时候就会自动调用对应的方法

    • 监听bean生命周期的方法有4种方式

    第一种:指定初始化和销毁方法

    1. 新建Car.class
    public class Car {
        
        public Car() {
            System.out.println("car 的构造方法执行了");
        }
    
        public void init(){
            System.out.println("car 的初始化方法执行了");
        }
    
        public void destory(){
            System.out.println("car 的销毁方法执行了");
        }
    }
    
    1. 新建MainConfigLifeCycle.class
    @Configuration
    public class MainConfigLifeCycle {
    
    //    通过@Bean的属性来指定那个是初始化方法,那个是销毁方法
        @Bean(initMethod = "init",destroyMethod = "destory")
        public Car car(){
            return  new Car();
        }
    }
    
    
    1. 测试代码
    class AnnotationStudyApplicationTests {
        
        @Test
        void contextLoads() {
    //        通过注解类容器上下文获取实例
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigLifeCycle.class);
            System.out.println("容器创建完成");
    //        关闭容器,这样会自动回调容器内bean的destory方法
            context.close();
        }
    
    }
    
    1. 打印输入为
    car 的构造方法执行了
    car 的初始化方法执行了
    容器创建完成
    car 的销毁方法执行了
    

    第二种:组件类实现InitializingBean(初始化), DisposableBean(销毁)接口

    1. 新建Car2.class,并且实现接口InitializingBean, DisposableBean,重写对应的方法
    public class Car2 implements InitializingBean, DisposableBean {
    
        public Car2() {
            System.out.println("car2 的构造方法执行了");
        }
    
        @Override
        public void destroy() throws Exception {
            System.out.println("car2 的销毁方法执行了");
            
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("car2 的初始化方法执行了");
        }
    }
    
    
    1. 在config类中注册该组件
    @Configuration
    public class MainConfigLifeCycle {
    
        @Bean
        public Car2 car2(){
            return  new Car2();
        }
      
    }
    
    
    1. 测试方法不变
    class AnnotationStudyApplicationTests {
        @Test
        void contextLoads() {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigLifeCycle.class);
            System.out.println("容器创建完成");
            context.close();
        }
    
    }
    
    1. 打印输出为
    car2 的构造方法执行了
    car2 的初始化方法执行了
    容器创建完成
    car2 的销毁方法执行了
    

    第三种:使用JSR250中的@PostConstruct和@PreDestroy

    • @PostConstruct:在组件创建完成,属性赋值完成后指定要执行的方法
    • @PreDestroy:在组件销毁前需要执行的方法,例如数据源销毁前,需要先断开一些连接等都可以使用该注解指定一个方法,在方法中进行关闭
    1. 新建Car3.class
    public class Car3 {
    
        public Car3() {
            System.out.println("car3 的构造方法执行了");
        }
    
        @PostConstruct
        public void postConstruct(){
            System.out.println("car3 已经创建完成");
        }
    
        @PreDestroy
        public void preDestory(){
            System.out.println("car3 即将销毁了,这是销毁之前执行的方法");
        }
    
    
    }
    
    
    1. config类中注册组件
    @Configuration
    public class MainConfigLifeCycle {
    
        @Bean
        public Car3 car3(){
            return  new Car3();
        }
      
    }
    
    1. 测试类不变
    class AnnotationStudyApplicationTests {
        @Test
        void contextLoads() {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigLifeCycle.class);
            System.out.println("容器创建完成");
            context.close();
        }
    
    }
    
    1. 打印输出为
    car3 的构造方法执行了
    car3 已经创建完成
    容器创建完成
    car3 即将销毁了,这是销毁之前执行的方法
    

    第四种:创建类实现接口BeanPostProcessor可以检测到全部组件的初始化

    • 实现BeanPostProcessor接口,重写方法,postProcessAfterInitialization和postProcessBeforeInitialization
    • postProcessBeforeInitialization:在初始化工作之前
    • postProcessAfterInitialization:在初始化工作之后
    1. 新建MyBeanProcessor.class实现接口
    public class MyBeanProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("初始化之前调用==>"+beanName+"==>"+bean);
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("初始化之后调用==>"+beanName+"==>"+bean);
            return bean;
        }
    }
    
    1. 在config类中注册组件自己的Processor,同时注册一些之前写的类,方便日志观察
    @Configuration
    public class MainConfigLifeCycle {
    
        @Bean(initMethod = "init",destroyMethod = "destory")
        public Car car(){
            return  new Car();
        }
        
        @Bean
        public Car2 car2(){
            return  new Car2();
        }
    
        @Bean
        public Car3 car3(){
            return  new Car3();
        }
    
    //    将监听所有组件注册的processor注册到容器中
        @Bean 
        public MyBeanProcessor myBeanProcessor(){
            return new MyBeanProcessor();
        }
        
    }
    
    1. 测试类
    class AnnotationStudyApplicationTests {
        
        @Test
        void contextLoads() {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigLifeCycle.class);
            System.out.println("容器创建完成");
            context.close();
        }
    
    }
    
    
    1. 打印输出为
    car 的构造方法执行了
    初始化之前调用==>car==>com.elitetyc.anno.annotation.beans.Car@d5b810e
    car 的初始化方法执行了
    初始化之后调用==>car==>com.elitetyc.anno.annotation.beans.Car@d5b810e
    16:29:57.840 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'car2'
    car2 的构造方法执行了
    初始化之前调用==>car2==>com.elitetyc.anno.annotation.beans.Car2@c88a337
    car2 的初始化方法执行了
    初始化之后调用==>car2==>com.elitetyc.anno.annotation.beans.Car2@c88a337
    16:29:57.841 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'car3'
    car3 的构造方法执行了
    初始化之前调用==>car3==>com.elitetyc.anno.annotation.beans.Car3@593aaf41
    car3 已经创建完成
    初始化之后调用==>car3==>com.elitetyc.anno.annotation.beans.Car3@593aaf41
    容器创建完成
    car3 即将销毁了,这是销毁之前执行的方法
    car2 的销毁方法执行了
    car 的销毁方法执行了
    

    注意:除了第四种方法是可以监听所有IOC中的组件初始化,其他的方法都只是针对自己这一个组件来的

    相关文章

      网友评论

          本文标题:springboot之IOC容器Bean声明周期监听

          本文链接:https://www.haomeiwen.com/subject/wstenctx.html