ApplicationContextAware的setApplicationContext方法是什么时候执行的
阅读原文时间:2021年04月21日阅读:1

ApplicationContextAware的setApplicationContext方法是什么时候执行的

可以肯定的是在从容器中getbean的过程中调用的,简单说下几个主要流程

  1. getbean到调用bean后处理器
    getbean的流程参见下图,主要参考标红字体部分

    从图中可以看出,最后会调用initializeBeanf方法又会调用applyBeanPostProcessorsBeforeInitialization、applyBeanPostProcessorsAfterInitialization方法,也就是调用bean后处理器。

  2. bean后处理器其中就有一个叫ApplicationContextAwareProcessor,其中的处理方法如下代码,就有调用到setApplicationContext方法

    @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>) () -> {
            invokeAwareInterfaces(bean);
            return null;
        }, acc);
    }
    else {
        invokeAwareInterfaces(bean);
    }
    
    return bean;
    } 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); } } }
  3. 你是不是会问ApplicationContextAwareProcessor什么时候放到容器中的,看org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory方法中就放进来了

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // Tell the internal bean factory to use the context's class loader etc.
    beanFactory.setBeanClassLoader(getClassLoader());
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

        // Configure the bean factory with context callbacks.
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        ······
    }

4.prepareBeanFactory又在org.springframework.context.support.AbstractApplicationContext#refresh方法中被调用,看是不是又回到容器初始化的入口了,整个流程是不是打通了