美文网首页工作生活
[深入学习]Spring Bean的生命周期(一)

[深入学习]Spring Bean的生命周期(一)

作者: lconcise | 来源:发表于2019-07-03 18:40 被阅读0次

    Spring Bean的生命周期指的是Bean从创建到初始化再到销毁的过程,这个过程由IOC容器管理。
    一个完成的生命周期后续会记录,这里我们主要记录一些和Bean生命周期相关的细节。

    • Bean的初始化和销毁(三种方式)
      1. @Bean
      2. InitializingBean&DisposableBean
      3. @PostContruct&@PreDestroy
    • BeanPostProcessor

    @Bean

    通过@Bean来注册Bean,也可以通过它来指定初始化和销毁方法。

    新建SpringBoot项目,然后创建一个User类。

    @Log
    public class User {
    
        public User() {
            log.info("调用无参构造创建User");
        }
    
        public void init() {
            log.info("初始化 User");
        }
    
        public void destroy() {
            log.info("销毁 User");
        }
    }
    

    然后配置类里注册该组件,并指定初始化和销毁方法。

    @Configuration
    public class WebConfig {
    
        @Bean(initMethod = "init", destroyMethod = "destroy")
        public User user() {
            return new User();
        }
    }
    

    其中initMethod = "init",destroyMethod = "destroy" 中的init,destroy 和User类中的init(),destroy()方法相对应。

    测试在SpringBoot入口类中进行测试

    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
            // 返回IOC容器,使用注解配置,传入配置类
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);
            context.close();
        }
    }
    

    测试结果


    由测试结果可以看出,创建IOC容器的时候,先调用无参构造方法,然后调用初始化方法,容器关闭的时候,调用销毁方法。

    InitializingBean&DisposableBean

    除了@Bean来指定初始化,销毁方法外,Spring 还提供了InitializingBean,DisposableBean接口,去实现接口,重写接口中的afterPropertiesSet(),destroy()方法,来实现Bean的初始化,销毁逻辑。

    创建一个Bird类,实现InitializingBean, DisposableBean

    @Log
    public class Bird implements InitializingBean, DisposableBean {
    
        public Bird() {
            log.info("调用无参构造创建Bird");
        }
    
        @Override
        public void destroy() throws Exception {
            log.info("销毁 Bird");
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            log.info("初始化 Bird");
        }
    }
    

    在配置类中注册该组件

    @Configuration
    public class WebConfig {
    
        @Bean
        public Bird bird() {
            return new Bird();
        }
    }
    

    测试在SpringBoot入口类中进行测试

    @Log
    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
            // 返回IOC容器,使用注解配置,传入配置类
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);
            log.info("== 容器创建完毕 ");
            context.close();
        }
    }
    

    测试结果

    image.png

    @PostConstruct&@PreDestroy

    还可以使用@PostConstruct,@PreDestroy来指定初始化,销毁方法。

    创建一个类Sweets

    @Log
    public class Sweets {
    
        public Sweets() {
            log.info("调用无参构造创建Sweets");
        }
    
        @PostConstruct
        public void init() {
            log.info("初始化 Sweets");
        }
    
        @PreDestroy
        public void destroy() {
            log.info("销毁 Sweets");
        }
    }
    

    在配置文件中注册该组件

    @Configuration
    public class WebConfig {
    
        @Bean
        public Sweets sweets() {
            return new Sweets();
        }
    }
    

    测试在SpringBoot入口类中进行测试

    @Log
    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
            // 返回IOC容器,使用注解配置,传入配置类
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);
            log.info("== 容器创建完毕 ");
            context.close();
        }
    }
    

    测试结果

    image.png

    BeanPostProcessor

    Spring 提供了BeanPostProcessor 接口,俗称Bean后置通知处理器,它提供了两个方法postProcessBeforeInitialization()和postProcessAfterInitialization(),其中postProcessBeforeInitialization()在组织初始化之前调用,postProcessAfterInitialization()在组件初始化之后调用。两个方法都传入两个参数:

    1. Object bean 当前组件对象
    2. String beanName 组件名称

    定义一个组件对象MyBeanPostProcessor,实现BeanPostProcessor

    @Log
    public class MyBeanPostProcessor implements BeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            log.info(beanName + " == 初始化之前调用");
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            log.info(beanName + " === 初始化之后调用");
            return bean;
        }
    }
    

    在配置文件中注册该组件

    @Configuration
    public class WebConfig {
    
        @Bean
        public Sweets sweets() {
            return new Sweets();
        }
    
        @Bean(initMethod = "init", destroyMethod = "destroy")
        public User user() {
            return new User();
        }
    
        @Bean
        public Bird bird() {
            return new Bird();
        }
    
        @Bean
        public MyBeanPostProcessor myBeanPostProcessor() {
            return new MyBeanPostProcessor();
        }
    }
    

    测试在SpringBoot入口类中进行测试

    @Log
    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
            // 返回IOC容器,使用注解配置,传入配置类
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);
            log.info("== 容器创建完毕 ");
            context.close();
        }
    }
    

    测试结果

    image.png

    代码地址:
    https://github.com/lbshold/springboot/tree/master/Spring-Register-Bean

    参考文章:
    https://mrbird.cc/Spring-Bean-Lifecycle.html
    https://www.cnblogs.com/zrtqsk/p/3735273.html

    相关文章

      网友评论

        本文标题:[深入学习]Spring Bean的生命周期(一)

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