• Spring BeanPostProcessor : ApplicationContextAwareProcessor


    (转)https://blog.csdn.net/andy_zhang2007/article/details/86287786

    概述

    ApplicationContextAwareProcessor是一个Spring内部工具,它实现了接口BeanPostProcessor,用于向实现了如下某种Aware接口的bean设置ApplicationContext中相应的属性:

    • EnvironmentAware
    • EmbeddedValueResolverAware
    • ResourceLoaderAware
    • ApplicationEventPublisherAware
    • MessageSourceAware
    • ApplicationContextAware

    如果bean实现了以上接口中的某几个,那么这些接口方法调用的先后顺序就是上面接口排列的先后顺序。

    注意,ApplicationContextAwareProcessor自己会被应用程序上下文自动注册到bean容器,不需要应用开发人员操心。具体的注册位置如下 :

    // 类 AbstractApplicationContext 代码片段
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        //...
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        //...
    }

    相应调用栈举例 :

    SpringApplication#run
    => SpringApplication#refresh
    ==> ServletWebServerApplicationContext#refresh
    ===> AbstractApplicationContext#refresh
    ====> AbstractApplicationContext#prepareBeanFactory

    ApplicationContextAwareProcessor 位于包package org.springframework.context.support;

    源代码分析

    package org.springframework.context.support;
    
    import java.security.AccessControlContext;
    import java.security.AccessController;
    import java.security.PrivilegedAction;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.Aware;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.beans.factory.config.EmbeddedValueResolver;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.context.ApplicationEventPublisherAware;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.context.EmbeddedValueResolverAware;
    import org.springframework.context.EnvironmentAware;
    import org.springframework.context.MessageSourceAware;
    import org.springframework.context.ResourceLoaderAware;
    import org.springframework.lang.Nullable;
    import org.springframework.util.StringValueResolver;
    
    // 注意,这里class前没有public修饰符,表明这个工具Spring没有打算给外部使用。
    class ApplicationContextAwareProcessor implements BeanPostProcessor {
    
        private final ConfigurableApplicationContext applicationContext;
    
        private final StringValueResolver embeddedValueResolver;
    
    
        /**
         * Create a new ApplicationContextAwareProcessor for the given context.
         * 使用给定的应用上下文创建一个ApplicationContextAwareProcessor实例,通常该方法
         * 由应用上下文对象自己调用,比如在类AbstractApplicationContext中 : 
         * new ApplicationContextAwareProcessor(this)
         */
        public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
            this.applicationContext = applicationContext;
            this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
        }
    
    
        // 接口BeanPostProcessor规定的方法,会在bean创建时,实例化后,初始化前,对bean对象应用
        @Override
        @Nullable
        public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
            AccessControlContext acc = null;
    
            if (System.getSecurityManager() != null &&
                    (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
                            bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
                            bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
                acc = this.applicationContext.getBeanFactory().getAccessControlContext();
            }
    
            if (acc != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    // 检查bean上是否实现了某个Aware接口,有的话做相应调用
                    invokeAwareInterfaces(bean);
                    return null;
                }, acc);
            }
            else {
                // 检查bean上是否实现了某个Aware接口,有的话做相应调用
                invokeAwareInterfaces(bean);
            }
    
            // 返回处理后的bean
            return bean;
        }
    
        // 检查bean上是否实现了某个Aware接口,有的话做相应调用
        private void invokeAwareInterfaces(Object bean) {
            if (bean instanceof Aware) {
                if (bean instanceof EnvironmentAware) {
                    ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
                }
                if (bean instanceof EmbeddedValueResolverAware) {
                    ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
                }
                if (bean instanceof ResourceLoaderAware) {
                    ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
                }
                if (bean instanceof ApplicationEventPublisherAware) {
                    ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
                }
                if (bean instanceof MessageSourceAware) {
                    ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
                }
                if (bean instanceof ApplicationContextAware) {
                    ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
                }
            }
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) {
            return bean;
        }
    
    }

     

  • 相关阅读:
    linux安装篇之mongodb安装及服务自启动配置
    Linux下启动mongodb
    java 实现 图片与byte 数组互相转换
    用java imageio调整图片DPI,例如从96调整为300
    StringRedisTemplate操作redis数据
    Docker 更换国内的Hub源
    2、Docker 基础安装和基础使用 一
    Centos 6.x Openssh 升级 7.7p1 版本
    1、Docker 简介
    2. Python环境安装
  • 原文地址:https://www.cnblogs.com/wllhq/p/13652404.html
Copyright © 2020-2023  润新知