架构のSpring扩展点(六):ApplicationContextAwareProcessor接口全解析,看完就懂

🍅 作者简介:大齐,自学Java入门,现在某国企担任初级架构师

🍅 有自己独立的学习方法,以及适合大部分人的学习路线,面试架构思路等

🍅 关注公众号【齐疾行者Code】,查看最新最全的知识分享

spring 的扩展点 是Spring易扩展的一个重要体现,熟悉这些扩展点的定义方式,以及其调用时机,不仅成为工作中利器,也能深度理解Spring框架的切入点。

ApplicationContextAwareProcessor扩展点 

ApplicationContextAwareProcessor定义

ApplicationContextAwareProcessor处理器继承自BeanPostProcessor,主要是对spring中实现自Aware接口的EnvironmentAware、ApplicationContextAware等进行后置处理。

ThreadScope即同一个线程内多次getBean是同一个对象,不同线程之间getBean对象不一样

class ApplicationContextAwareProcessor implements BeanPostProcessor {
    //SpringContext上下文
    private final ConfigurableApplicationContext applicationContext;
    //字符串属性值解析器
    private final StringValueResolver embeddedValueResolver;

    public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
        this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
    }

    @Nullable
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //具体的几个实现Aware接口的接口,这几个接口只有对应的setXX函数
        if (!(bean instanceof EnvironmentAware) && !(bean instanceof EmbeddedValueResolverAware) && !(bean instanceof ResourceLoaderAware) && !(bean instanceof ApplicationEventPublisherAware) && !(bean instanceof MessageSourceAware) && !(bean instanceof ApplicationContextAware) && !(bean instanceof ApplicationStartupAware)) {
            return bean;
        } else {
            AccessControlContext acc = null;
            if (System.getSecurityManager() != null) {
                acc = this.applicationContext.getBeanFactory().getAccessControlContext();
            }

            if (acc != null) {
                AccessController.doPrivileged(() -> {
                    //执行设置操作
                    this.invokeAwareInterfaces(bean);
                    return null;
                }, acc);
            } else {
                //执行设置操作
                this.invokeAwareInterfaces(bean);
            }

            return bean;
        }
    }
    //具体的执行操作
    private void invokeAwareInterfaces(Object bean) {
        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 ApplicationStartupAware) {
            ((ApplicationStartupAware)bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
        }

        if (bean instanceof ApplicationContextAware) {
            ((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
        }

    }
}

ApplicationContextAwareProcessor源码

注册时机

ApplicationContextAwareProcessor是在AbstractApplicationContext#refresh#prepareBeanFactory方法中注册的

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {


      ......
      
      // Tell the subclass to refresh the internal bean factory.
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      // Prepare the bean factory for use in this context.
      prepareBeanFactory(beanFactory);
      
      ......
      
      }
 }

AbstractApplicationContext#refresh方法

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // Tell the internal bean factory to use the context's class loader etc.
    //设置类加载器,告诉bean工厂使用
    //加载spring的上下文的扩展加载器作为级的类加载器
    beanFactory.setBeanClassLoader(getClassLoader());
    
    if (!shouldIgnoreSpel) {
      //不需要忽略spl表达式解析
      beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    }
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // Configure the bean factory with context callbacks.
    //在这一步将aware的后置加载器进行注册
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    //将下列需要后置处理器感知的接口实现类j进行剔除
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);

    ........

    // Register early post-processor for detecting inner beans as ApplicationListeners.
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // Detect a LoadTimeWeaver and prepare for weaving, if found.
    if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      // Set a temporary ClassLoader for type matching.
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    // Register default environment beans.
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
    if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
      beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
    }
  }

调用时机

调用时机同BeanPostProcessor,在bean初始化前后被调用,具体的流程如下:

图片

  • 在AbstractApplicationContext类的finishBeanFactoryInitialization方法中,进行初始化bean实际是调用子类了DefaultListableBeanFactory的finishBeanFactoryInitialization方法

public void preInstantiateSingletons() throws BeansException {
    if (logger.isTraceEnabled()) {
      logger.trace("Pre-instantiating singletons in " + this);
    }

    // Iterate over a copy to allow for init methods which in turn register new bean definitions.
    // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    ........
}    
  • 在AbstractBeanFactory类的doGetBean方法中,调用子类的createBean方法完成创建工作

protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException

关注公众号:齐疾行者Code 私信资料 >>领取超过500份资料总结的整理文档,覆盖所有后端知识点

👉 近期文章精选

架构のSpring扩展点(一):上下文创建前的动态处理-ApplicationContextInitializer

架构のSpring扩展点(二):Bean定义操作-BeanDefinitionRegistryPostProcessor

架构のSpring扩展点(三):Bean生命周期操作-InstantiationAwareBeanPostProcessor

架构のSpring扩展点(四):Bean初始化时对象自动注入-Aware全解析

架构のSpring扩展点(五):如何保证在同一线程内获取的bean是同一对象-自定义Scope

认知结构的提升,需要合适的思考方法-架构提升

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值