zoukankan      html  css  js  c++  java
  • Spring源码系列5

    一、Bean初始化的几种方式

    1.使用@Bean指定初始化和销毁方法

    @Configuration
    public class LifeCycleConfig {
    
        @Bean(initMethod = "init", destroyMethod = "destroy")
        public Color color() {
            return new Color();
        }
    
    }
    
    public class Color {
    
        public Color() {
            System.out.println("Color construct……");
        }
    
        public void init() {
            System.out.println("Color init……");
        }
    
        public void destroy() {
            System.out.println("Color destroy……");
        }
    
    }
    
    打印结果:
    Color construct……
    Color init……
    Color destroy……

    2.实现InitializingBean和Disposable接口

    该方式的Bean会与Spring产生耦合,不推荐使用。

    @Configuration
    public class LifeCycleConfig {
    
        @Bean
        public Apple apple() {
            return new Apple();
        }
    
    }
    
    public class Apple implements InitializingBean, DisposableBean {
    
        public Apple() {
            System.out.println("Apple construct……");
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("Apple init……");
        }
    
        @Override
        public void destroy() throws Exception {
            System.out.println("Apple destroy");
        }
    }
    
    打印结果:
    Apple construct……
    Apple init……
    Apple destroy……

    3.使用JSR250提供的@PostConstruct和@PreDestroy

    @PostConstruct和@PreDestroy这两个注解是JSR-250提供的。

    @Configuration
    public class LifeCycleConfig {
    
        @Bean
        public Banana banana() {
            return new Banana();
        }
    
    }
    
    public class Banana {
    
        public Banana() {
            System.out.println("Banana construct……");
        }
    
        @PostConstruct
        public void init() {
            System.out.println("Banana init……");
        }
    
        @PreDestroy
        public void destroy() {
            System.out.println("Banana destory……");
        }
    
    }
    
    打印结果:
    Banana construct……
    Banana init……
    Banana destory……

    4.使用BeanPostProcessor

    使用后置处理器,BeanPostProcessor接口中定义了两个方法:postProcessBeforeInitialization和postProcessAfterInitialization方法,分别在Bean的初始化方法执行的前后执行。

    该方式本质上不算是声明Bean的初始化方式,而仅仅是对bean的初始化方法的功能增强,但其在Spring中使用非常广泛,例如@Autowired。

    说明:后置处理器的方式是Bean的统一前置后置处理,而不是基于某一个bean。从下面程序执行结果也可以看出,不仅Car实例被后置处理器处理了,Spring中的Bean也被后置处理器处理了。

    @Configuration
    public class LifeCycleConfig {
    
        @Bean
        public Car car() {
            return new Car();
        }
    
        @Bean
        public MyBeanPostProcessor myBeanPostProcessor() {
            return new MyBeanPostProcessor();
        }
    
    }
    
    public class Car {
    
        public Car() {
            System.out.println("Car construct……");
        }
    
    }
    
    //后置处理器
    public class MyBeanPostProcessor implements BeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("后置处理器BeforeInitialization:  " + beanName);
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("后置处理器AfterInitialization:  " + beanName);
            return bean;
        }
    }
    
    打印结果:
    后置处理器BeforeInitialization:  org.springframework.context.event.internalEventListenerProcessor
    后置处理器AfterInitialization:  org.springframework.context.event.internalEventListenerProcessor
    后置处理器BeforeInitialization:  org.springframework.context.event.internalEventListenerFactory
    后置处理器AfterInitialization:  org.springframework.context.event.internalEventListenerFactory
    Car construct……
    后置处理器BeforeInitialization:  car
    后置处理器AfterInitialization:  car

    二、Bean初始化的几种方式优先级

    上面介绍了几种Bean的初始化和销毁方式,那么问题来了,这几种方式的优先级是怎样的呢?我们可以写个程序测试一下,只需要把几种方式同时都用上即可。

    public class Mix implements InitializingBean, DisposableBean, BeanPostProcessor {
    
        /**
         * 构造方法
         */
        public Mix() {
            System.out.println("construct");
        }
    
        /*********************(第一顺序调用)下面使用JSR250方式指定*******************/
        @PostConstruct
        private void jsr250Init() {
            System.out.println("JSR250-->@PostConstruct");
        }
    
        @PreDestroy
        private void jsr250PreDestroy() {
            System.out.println("JSR250-->@PreDestroy");
        }
    
        /*********************(第二顺序调用)下面使用实现接口的方式指定*******************/
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("实现InitializingBean接口-->afterPropertiesSet");
        }
    
        @Override
        public void destroy() throws Exception {
            System.out.println("实现DisposableBean接口-->destroy");
        }
    
        /*********************(第三顺序调用)下面使用@Bean方式的属性指定*******************/
        private void initMethod() {
            System.out.println("@Bean指定的方法-->initMethod");
        }
    
        private void destroyMethod() {
            System.out.println("@Bean指定的方法-->destroyMethod");
        }
    
    }

    配置类

    @Configuration
    public class MixConfig {
    
        @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
        public Mix mix() {
            return new Mix();
        }
    
        @Bean
        public MyBeanPostProcessor myBeanPostProcessor() {
            return new MyBeanPostProcessor();
        }
    
    }

    下面就来调用一下,看看执行结果

    public class MixMain {
    
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MixConfig.class);
            context.destroy();
        }
    }

    执行结果如下:

    后置处理器BeforeInitialization:  org.springframework.context.event.internalEventListenerProcessor
    后置处理器AfterInitialization:  org.springframework.context.event.internalEventListenerProcessor
    后置处理器BeforeInitialization:  org.springframework.context.event.internalEventListenerFactory
    后置处理器AfterInitialization:  org.springframework.context.event.internalEventListenerFactory
    
    construct……
    后置处理器BeforeInitialization:  mix
    JSR250-->@PostConstruct
    实现InitializingBean接口-->afterPropertiesSet
    @Bean指定的方法-->initMethod
    后置处理器AfterInitialization:  mix
    
    JSR250-->@PreDestroy
    实现DisposableBean接口-->destroy
    @Bean指定的方法-->destroyMethod

    因此,几种初始化调用顺序如下图所示:

    三、Bean销毁的几种方式优先级

    Bean的销毁就不再写程序去验证了,在Spring源码系列4 - Bean的生命周期中已经分析过源码了。Bean销毁的执行顺序与Bean初始化的执行顺序是一致的。

  • 相关阅读:
    SpringBoot配置文件(2)
    SpringBoot配置文件(1)
    java8新特性之stream流
    java8新特性之Lambda表达式
    zoj 1709 Oil Deposits
    zoj 2110 Tempter of the Bone
    poj 2823 Sliding Window
    fzu 1894 志愿者选拔
    hdoj 1754 I Hate It
    poj2404中国邮递员
  • 原文地址:https://www.cnblogs.com/rouqinglangzi/p/12496953.html
Copyright © 2011-2022 走看看