• Spring之BeanPostProcessor(bean后置处理器)


    一句话:bean后置处理器就是对bean的生命周期的各阶段的增强

    1、bean生命周期

    启动类:

    @SpringBootApplication
    public class A03 {
        public static void main(String[] args) {
            //创建容器
            ConfigurableApplicationContext context = 
            SpringApplication.run(A03.class, args);
            //关闭容器
            context.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    添加扫描bean

    @Component
    @Slf4j
    public class LifeCycleBean {
    
        public LifeCycleBean() {
            log.debug("bean生命周期>>>>>>>>>>>>>>>>>>>构造");
        }
    
        @Autowired
        public void autowire(@Value("${JAVA_HOME}") String home) {
            log.debug("bean生命周期>>>>>>>>>>>>>>>>>>依赖注入: {}", home);
        }
    
        @PostConstruct
        public void init() {
            log.debug("bean生命周期>>>>>>>>>>>>>>>>>>>初始化");
        }
    
        @PreDestroy
        public void destroy() {
            log.debug("bean生命周期>>>>>>>>>>>>>>>>>>>销毁");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    输出结果:

    [INFO ] 18:03:31.555 [main] o.s.b.w.e.tomcat.TomcatWebServer    - Tomcat initialized with port(s): 8080 (http) 
    [INFO ] 18:03:31.563 [main] o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"] 
    [INFO ] 18:03:31.564 [main] o.a.catalina.core.StandardService   - Starting service [Tomcat] 
    [INFO ] 18:03:31.564 [main] o.a.catalina.core.StandardEngine    - Starting Servlet engine: [Apache Tomcat/9.0.53] 
    [INFO ] 18:03:31.662 [main] o.a.c.c.C.[Tomcat].[localhost].[/]  - Initializing Spring embedded WebApplicationContext 
    [INFO ] 18:03:31.663 [main] o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 994 ms 
    [DEBUG] 18:03:31.710 [main] com.xc.a03.LifeCycleBean            - bean生命周期>>>>>>>>>>>>>>>>>>>构造 
    [DEBUG] 18:03:31.713 [main] com.xc.a03.LifeCycleBean            - bean生命周期>>>>>>>>>>>>>>>>>>依赖注入: E:\java\jdk\jdk8\tools 
    [DEBUG] 18:03:31.714 [main] com.xc.a03.LifeCycleBean            - bean生命周期>>>>>>>>>>>>>>>>>>>初始化 
    [INFO ] 18:03:31.917 [main] o.s.b.a.w.s.WelcomePageHandlerMapping - Adding welcome page: class path resource [static/index.html] 
    [INFO ] 18:03:31.986 [main] c.a.d.s.b.a.DruidDataSourceAutoConfigure - Init DruidDataSource 
    [INFO ] 18:03:32.055 [main] c.a.druid.pool.DruidDataSource      - {dataSource-1} inited 
    [INFO ] 18:03:32.416 [main] o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"] 
    [INFO ] 18:03:32.429 [main] o.a.c.c.C.[Tomcat].[localhost].[/]  - Initializing Spring DispatcherServlet 'dispatcherServlet' 
    [INFO ] 18:03:32.430 [main] o.s.web.servlet.DispatcherServlet   - Initializing Servlet 'dispatcherServlet' 
    [TRACE] 18:03:32.430 [main] o.s.web.servlet.DispatcherServlet   - Detected org.springframework.web.multipart.support.StandardServletMultipartResolver@4eed2acf 
    [TRACE] 18:03:32.430 [main] o.s.web.servlet.DispatcherServlet   - Detected org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver@36fc05ff 
    [TRACE] 18:03:32.430 [main] o.s.web.servlet.DispatcherServlet   - Detected org.springframework.web.servlet.theme.FixedThemeResolver@57c47a9e 
    [TRACE] 18:03:32.430 [main] o.s.web.servlet.DispatcherServlet   - Detected DefaultRequestToViewNameTranslator 
    [TRACE] 18:03:32.430 [main] o.s.web.servlet.DispatcherServlet   - Detected SessionFlashMapManager 
    [DEBUG] 18:03:32.430 [main] o.s.web.servlet.DispatcherServlet   - enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data 
    [INFO ] 18:03:32.430 [main] o.s.web.servlet.DispatcherServlet   - Completed initialization in 0 ms 
    [INFO ] 18:03:32.432 [main] o.s.b.w.e.tomcat.TomcatWebServer    - Tomcat started on port(s): 8080 (http) with context path '' 
    [INFO ] 18:03:32.441 [main] com.xc.a03.A03                      - Started A03 in 2.152 seconds (JVM running for 3.009) 
    [INFO ] 18:03:32.713 [main] c.a.druid.pool.DruidDataSource      - {dataSource-1} closing ... 
    [INFO ] 18:03:32.714 [main] c.a.druid.pool.DruidDataSource      - {dataSource-1} closed 
    [DEBUG] 18:03:32.715 [main] com.xc.a03.LifeCycleBean            - bean生命周期>>>>>>>>>>>>>>>>>>>销毁 
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    2、常用的bean后置处理器接口

    2.1、初始化-Bean后置处理器

    • BeanPostProcessor是bean后置处理器最底层接口
    • 两个方法返回的bean会替换原来的bean
    • 初始化阶段在实例化和属性填充之后
    • 初始化之前执行:解析注解@PostConstruct、@ConfigurationProperties
    • 初始化之后执行:代理增强
    public interface BeanPostProcessor {
    	//bean初始化前执行
        @Nullable
        default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }
    	//bean初始化后执行
        @Nullable
        default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 自定义初始化后置处理器
    @Component
    @Slf4j
    public class MyBeanPostProcessor implements BeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            if (beanName.equals("lifeCycleBean"))
                log.debug("初始化后置处理器>>>>>>> 初始化之前执行, 这里返回的对象会替换掉原本的 bean, 如 @PostConstruct、@ConfigurationProperties");
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (beanName.equals("lifeCycleBean"))
                log.debug("初始化后置处理器>>>>>>>  初始化之后执行, 这里返回的对象会替换掉原本的 bean, 如代理增强");
            return bean;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2.2、实例化-Bean后置处理器

    • BeanPostProcessor的扩展接口(子接口)
    • 实例化之前执行:返回的bean对象可能是要使用的代理,而不是目标bean,从而有效地抑制了目标bean的默认实例化。如果此方法返回非null对象,则bean创建过程将被短路(也就是正常bean实例化的后续流程不再执行)
    • 实例化之后执行:返回结果为true时,说明应该为bean设置属性。如果返回结果为false,跳过bean属性赋值环节
    • 依赖注入阶段执行:解析注解@Autowired、@Value、@Resource
    • postProcessPropertyValues:这个方法在spring低版本中使用,在高版本已经过时了,使用postProcessProperties代替
    public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
    	//bean实例化前执行
        @Nullable
        default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            return null;
        }
    	//bean实例化后执行
        default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            return true;
        }
    	//依赖注入阶段执行
        @Nullable
        default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
            return null;
        }
    
        /** @deprecated */
        @Deprecated
        @Nullable
        default PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
            return pvs;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 自定义实例化后置处理器
    @Component
    @Slf4j
    public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            if (beanName.equals("lifeCycleBean"))
                log.debug("实例化后置处理器>>>>>>>  实例化之前执行, 这里返回的对象会替换掉原本的 bean");
            return null;
        }
    
        @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            if (beanName.equals("lifeCycleBean")) {
                log.debug("实例化后置处理器>>>>>>>实例化之后执行, 这里如果返回 false 会跳过依赖注入阶段");
    //            return false;
            }
            return true;
        }
    
        @Override
        public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
            if (beanName.equals("lifeCycleBean"))
                log.debug("实例化后置处理器>>>>>>> 依赖注入阶段执行, 如 @Autowired、@Value、@Resource");
            return pvs;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    2.3、销毁-Bean后置处理器

    • BeanPostProcessor的扩展接口(子接口)
    • 销毁之前执行:解析注解@PreDestroy
    public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
        //这里实现销毁对象的逻辑
        void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
        //判断是否需要处理这个对象的销毁
        default boolean requiresDestruction(Object bean) {
            return true;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 自定义销毁后置处理器
    @Component
    @Slf4j
    public class MyDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor {
    
        @Override
        public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
            if (beanName.equals("lifeCycleBean"))
                log.debug("销毁后置处理器>>>>>>>  销毁之前执行, 如 @PreDestroy");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    生命周期bean添加后置处理器后输出结果:

    [INFO ] 18:07:14.639 [main] o.s.b.w.e.tomcat.TomcatWebServer    - Tomcat initialized with port(s): 8080 (http) 
    [INFO ] 18:07:14.646 [main] o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"] 
    [INFO ] 18:07:14.646 [main] o.a.catalina.core.StandardService   - Starting service [Tomcat] 
    [INFO ] 18:07:14.646 [main] o.a.catalina.core.StandardEngine    - Starting Servlet engine: [Apache Tomcat/9.0.53] 
    [INFO ] 18:07:14.715 [main] o.a.c.c.C.[Tomcat].[localhost].[/]  - Initializing Spring embedded WebApplicationContext 
    [INFO ] 18:07:14.715 [main] o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 867 ms 
    [DEBUG] 18:07:14.748 [main] c.x.a.MyInstantiationAwareBeanPostProcessor - 实例化后置处理器>>>>>>>  实例化之前执行, 这里返回的对象会替换掉原本的 bean 
    [DEBUG] 18:07:14.749 [main] com.xc.a03.LifeCycleBean            - bean生命周期>>>>>>>>>>>>>>>>>>>构造 
    [DEBUG] 18:07:14.750 [main] c.x.a.MyInstantiationAwareBeanPostProcessor - 实例化后置处理器>>>>>>>实例化之后执行, 这里如果返回 false 会跳过依赖注入阶段 
    [DEBUG] 18:07:14.750 [main] c.x.a.MyInstantiationAwareBeanPostProcessor - 实例化后置处理器>>>>>>> 依赖注入阶段执行,@Autowired@Value@Resource 
    [DEBUG] 18:07:14.751 [main] com.xc.a03.LifeCycleBean            - bean生命周期>>>>>>>>>>>>>>>>>>依赖注入: E:\java\jdk\jdk8\tools 
    [DEBUG] 18:07:14.752 [main] com.xc.a03.MyBeanPostProcessor      - 初始化后置处理器>>>>>>> 初始化之前执行, 这里返回的对象会替换掉原本的 bean,@PostConstruct@ConfigurationProperties 
    [DEBUG] 18:07:14.752 [main] com.xc.a03.LifeCycleBean            - bean生命周期>>>>>>>>>>>>>>>>>>>初始化 
    [DEBUG] 18:07:14.752 [main] com.xc.a03.MyBeanPostProcessor      - 初始化后置处理器>>>>>>>  初始化之后执行, 这里返回的对象会替换掉原本的 bean, 如代理增强 
    [INFO ] 18:07:14.920 [main] o.s.b.a.w.s.WelcomePageHandlerMapping - Adding welcome page: class path resource [static/index.html] 
    [INFO ] 18:07:14.986 [main] c.a.d.s.b.a.DruidDataSourceAutoConfigure - Init DruidDataSource 
    [INFO ] 18:07:15.056 [main] c.a.druid.pool.DruidDataSource      - {dataSource-1} inited 
    [INFO ] 18:07:15.273 [main] o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"] 
    [INFO ] 18:07:15.285 [main] o.a.c.c.C.[Tomcat].[localhost].[/]  - Initializing Spring DispatcherServlet 'dispatcherServlet' 
    [INFO ] 18:07:15.285 [main] o.s.web.servlet.DispatcherServlet   - Initializing Servlet 'dispatcherServlet' 
    [TRACE] 18:07:15.286 [main] o.s.web.servlet.DispatcherServlet   - Detected org.springframework.web.multipart.support.StandardServletMultipartResolver@57c47a9e 
    [TRACE] 18:07:15.286 [main] o.s.web.servlet.DispatcherServlet   - Detected org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver@642505c7 
    [TRACE] 18:07:15.286 [main] o.s.web.servlet.DispatcherServlet   - Detected org.springframework.web.servlet.theme.FixedThemeResolver@4339e0de 
    [TRACE] 18:07:15.286 [main] o.s.web.servlet.DispatcherServlet   - Detected DefaultRequestToViewNameTranslator 
    [TRACE] 18:07:15.286 [main] o.s.web.servlet.DispatcherServlet   - Detected SessionFlashMapManager 
    [DEBUG] 18:07:15.286 [main] o.s.web.servlet.DispatcherServlet   - enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data 
    [INFO ] 18:07:15.286 [main] o.s.web.servlet.DispatcherServlet   - Completed initialization in 0 ms 
    [INFO ] 18:07:15.287 [main] o.s.b.w.e.tomcat.TomcatWebServer    - Tomcat started on port(s): 8080 (http) with context path '' 
    [INFO ] 18:07:15.295 [main] com.xc.a03.A03                      - Started A03 in 1.781 seconds (JVM running for 2.529) 
    [INFO ] 18:07:15.581 [main] c.a.druid.pool.DruidDataSource      - {dataSource-1} closing ... 
    [INFO ] 18:07:15.582 [main] c.a.druid.pool.DruidDataSource      - {dataSource-1} closed 
    [DEBUG] 18:07:15.584 [main] c.x.a.MyDestructionAwareBeanPostProcessor - 销毁后置处理器>>>>>>>  销毁之前执行,@PreDestroy 
    [DEBUG] 18:07:15.584 [main] com.xc.a03.LifeCycleBean            - bean生命周期>>>>>>>>>>>>>>>>>>>销毁 
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    3、模板方法设计模式,扩展bean后置处理器

    • getBean方法执行流程步骤已确定
    • 后置处理器接口集合遍历,添加后置处理器只需要bean工厂添加到后置处理器集合汇总即可
    public class TestMethodTemplate {
        public static void main(String[] args) {
            MyBeanFactory beanFactory = new MyBeanFactory();
            beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Autowired"));
            beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Resource"));
            beanFactory.getBean();
        }
    }
    
    // 模板方法
    class MyBeanFactory {
        private final List<BeanPostProcessor> processors = new ArrayList<>();
    
        public void addBeanPostProcessor(BeanPostProcessor processor) {
            processors.add(processor);
        }
    
        public Object getBean() {
            Object bean = new Object();
            System.out.println("构造 " + bean);
            System.out.println("依赖注入 " + bean); // @Autowired, @Resource
            for (BeanPostProcessor processor : processors) {
                processor.inject(bean);
            }
            System.out.println("初始化 " + bean);
            return bean;
        }
    }
    
    interface BeanPostProcessor {
        public void inject(Object bean); // 对依赖注入阶段的扩展
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    输出结果:

    构造 java.lang.Object@533ddba
    依赖注入 java.lang.Object@533ddba
    解析 @Autowired
    解析 @Resource
    初始化 java.lang.Object@533ddba
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4、bean后置处理器排序

    • 实现了 PriorityOrdered 接口的优先级最高
    • 实现了 Ordered 接口与加了 @Order 注解的平级, 按数字升序
    • 其它的排在最后
    public class TestProcessOrder {
        public static void main(String[] args) {
            DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
            AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
    		//排序
            List<BeanPostProcessor> list = Arrays.asList(new P1(), new P2(), new P3(), new P4(), new P5());
            list.sort(beanFactory.getDependencyComparator());
    		//遍历执行后置处理器的初始化之前方法
            list.forEach(processor->{
                processor.postProcessBeforeInitialization(new Object(), "");
            });
        }
    }
    
    @Order(1)
    class P1 implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("postProcessBeforeInitialization @Order(1)");
            return bean;
        }
    }
    
    @Order(2)
    class P2 implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("postProcessBeforeInitialization @Order(2)");
            return bean;
        }
    }
    
    class P3 implements BeanPostProcessor, PriorityOrdered {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("postProcessBeforeInitialization PriorityOrdered getOrder() == 100");
            return bean;
        }
        @Override
        public int getOrder() {
            return 100;
        }
    }
    
    class P4 implements BeanPostProcessor, Ordered {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("postProcessBeforeInitialization Ordered getOrder() == 0");
            return bean;
        }
        @Override
        public int getOrder() {
            return 0;
        }
    }
    
    class P5 implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("postProcessBeforeInitialization 无排序接口");
            return bean;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    输出结果:

    Connected to the target VM, address: '127.0.0.1:63224', transport: 'socket'
    postProcessBeforeInitialization PriorityOrdered getOrder() == 100
    postProcessBeforeInitialization Ordered getOrder() == 0
    postProcessBeforeInitialization @Order(1)
    postProcessBeforeInitialization @Order(2)
    postProcessBeforeInitialization 无排序接口
    Disconnected from the target VM, address: '127.0.0.1:63224', transport: 'socket'
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    5、bean后置处理器实现类的作用

    准备bean:

    @Slf4j
    public class Bean1 {
    
        private Bean2 bean2;
    
        @Autowired
        public void setBean2(Bean2 bean2) {
            log.debug("@Autowired 生效: {}", bean2);
            this.bean2 = bean2;
        }
    
        @Autowired
        private Bean3 bean3;
    
        @Resource
        public void setBean3(Bean3 bean3) {
            log.debug("@Resource 生效: {}", bean3);
            this.bean3 = bean3;
        }
    
        private String home;
    
        @Autowired
        public void setHome(@Value("${JAVA_HOME}") String home) {
            log.debug("@Value 生效: {}", home);
            this.home = home;
        }
    
        @PostConstruct
        public void init() {
            log.debug("@PostConstruct 生效");
        }
    
        @PreDestroy
        public void destroy() {
            log.debug("@PreDestroy 生效");
        }
    
        @Override
        public String toString() {
            return "Bean1{" +
                   "bean2=" + bean2 +
                   ", bean3=" + bean3 +
                   ", home='" + home + '\'' +
                   '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    public class Bean2 {
    }
    
    • 1
    • 2
    public class Bean3 {
    }
    
    • 1
    • 2
    @ConfigurationProperties(prefix = "java")
    public class Bean4 {
    
        private String home;
    
        private String version;
    
        public String getHome() {
            return home;
        }
    
        public void setHome(String home) {
            this.home = home;
        }
    
        public String getVersion() {
            return version;
        }
    
        public void setVersion(String version) {
            this.version = version;
        }
    
        @Override
        public String toString() {
            return "Bean4{" +
                   "home='" + home + '\'' +
                   ", version='" + version + '\'' +
                   '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    启动类:

    public class A04 {
        public static void main(String[] args) {
            // GenericApplicationContext 是一个【干净】的容器
            GenericApplicationContext context = new GenericApplicationContext();
    
            // 用原始方法注册三个 bean
            context.registerBean("bean1", Bean1.class);
            context.registerBean("bean2", Bean2.class);
            context.registerBean("bean3", Bean3.class);
            context.registerBean("bean4", Bean4.class);
    
            // 解析表达式
            context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
            // @Autowired @Value
            context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
    
            // @Resource @PostConstruct @PreDestroy
            context.registerBean(CommonAnnotationBeanPostProcessor.class); 
    
    		//解析配置文件properties对象
            ConfigurationPropertiesBindingPostProcessor.register(context.getDefaultListableBeanFactory());
    
            // 执行beanFactory后处理器, 添加bean后处理器, 初始化所有单例
            context.refresh(); 
    
            System.out.println(context.getBean(Bean1.class));
    
            // 销毁容器
            context.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    输出结果:

    [DEBUG] 22:37:41.613 [main] com.xc.a04.Bean1                    - @Resource 生效: com.xc.a04.Bean3@f2f2cc1 
    [DEBUG] 22:37:41.661 [main] com.xc.a04.Bean1                    - @Value 生效: E:\java\jdk\jdk8\tools 
    [DEBUG] 22:37:41.664 [main] com.xc.a04.Bean1                    - @Autowired 生效: com.xc.a04.Bean2@2fd6b6c7 
    [DEBUG] 22:37:41.664 [main] com.xc.a04.Bean1                    - @PostConstruct 生效 
    Bean1{bean2=com.xc.a04.Bean2@2fd6b6c7, bean3=com.xc.a04.Bean3@f2f2cc1, home='E:\java\jdk\jdk8\tools'}
    [DEBUG] 22:37:41.905 [main] com.xc.a04.Bean1                    - @PreDestroy 生效 
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    总结:后置处理器解析@Autowired@Resource@PostConstruct等一些列注解处理bean生命周期阶段(依赖注入, 初始化)的扩展功能

  • 相关阅读:
    LeetCode 1769. 移动所有球到每个盒子所需的最小操作数
    [SQL开发笔记]在windows系统安装Postgres
    『忘了再学』Shell基础 — 21、变量的测试与内容置换
    05【Redis的发布订阅】
    SpringBoot 使用异步方法
    功率放大器的作用和工作原理是什么
    python爬虫基础知识-开发者工具
    机器学习KNN最邻近分类算法
    乐高式扩展:在Seal软件供应链防火墙中轻松集成代码规范工具
    聊一聊mysql的MVC
  • 原文地址:https://blog.csdn.net/qq_35512802/article/details/126037181