簡體   English   中英

ApplicationContextAware 在 Spring 中是如何工作的?

[英]How does ApplicationContextAware work in Spring?

在 spring 中,如果 bean 實現了ApplicationContextAware ,那么它就可以訪問applicationContext 因此它能夠獲取其他bean。 例如

public class SpringContextUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;     

    public void setApplicationContext(ApplicationContext context) throws BeansException {
      applicationContext = context;
    }

    public static ApplicationContext getApplicationContext() {
      return applicationContext;
    }
}

然后SpringContextUtil.getApplicationContext.getBean("name")就可以得到 bean “name”了。

為此,我們應該將此SpringContextUtil放在applications.xml ,例如

<bean class="com.util.SpringContextUtil" />

這里 bean SpringContextUtil不包括屬性applicationContext 我猜當 spring bean 初始化時,這個屬性被設置。 但這是如何做到的? 如何調用setApplicationContext方法?

當 spring 實例化 bean 時,它會尋找幾個接口,如ApplicationContextAwareInitializingBean 如果找到它們,則調用這些方法。 例如(非常簡化)

Class<?> beanClass = beanDefinition.getClass();
Object bean = beanClass.newInstance();
if (bean instanceof ApplicationContextAware) {
    ((ApplicationContextAware) bean).setApplicationContext(ctx);
}

請注意,在較新的版本中,最好使用注解,而不是實現特定於 spring 的接口。 現在您可以簡單地使用:

@Inject // or @Autowired
private ApplicationContext ctx;

Spring源碼解釋ApplicationContextAware如何工作
當您使用ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
AbstractApplicationContext類中, refresh()方法具有以下代碼:

// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

進入這個方法, beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); 將 ApplicationContextAwareProcessor 添加到 AbstractrBeanFactory。

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));
...........

spring 在AbstractAutowireCapableBeanFactory初始化 bean 時,在initializeBean方法中,調用applyBeanPostProcessorsBeforeInitialization來實現 bean 的后期處理。 該過程包括注入applicationContext。

@Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {
        Object result = existingBean;
        for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
            result = beanProcessor.postProcessBeforeInitialization(result, beanName);
            if (result == null) {
                return result;
            }
        }
        return result;
    }

當 BeanPostProcessor 實現 Object 時執行 postProcessBeforeInitialization 方法,例如之前添加的ApplicationContextAwareProcessor

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(
                        new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
            }
            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);
            }
        }
    }

任何希望被通知它運行的 ApplicationContext 的對象要實現的接口。

以上摘自 Spring doc 網站https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ApplicationContextAware.html

所以,它似乎是在 Spring 容器啟動時調用的,如果你當時想做點什么。

它只有一種設置上下文的方法,因此您將獲得上下文並在我認為現在已經在上下文中執行某些操作。

ApplicationContextAware Interface,當前應用上下文,通過它可以調用spring容器服務。 我們可以通過類中的以下方法獲取當前的 applicationContext 實例

public void setApplicationContext(ApplicationContext context) throws BeansException.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM