ApplicationContextAware如何在Spring中运行?

时间:2014-02-04 12:52:42

标签: java spring

在Spring中,如果bean实现了ApplicationContextAware,那么它就能够访问applicationContext。因此它能够获得其他豆类。 例如

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

4 个答案:

答案 0 :(得分:79)

当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;

答案 1 :(得分:5)

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 post进程。该过程包括注入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);
            }
        }
    }

答案 2 :(得分:0)

希望由其运行在其中的ApplicationContext通知的任何对象都将实现该接口。

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

因此,如果您当时想做些事情,它似乎在Spring容器启动时被调用。

它只有一种设置上下文的方法,因此您将获得上下文并在我认为的上下文中已经做过一些事情。

答案 3 :(得分:-1)

ApplicationContextAware Interface,当前的应用程序上下文,通过它可以调用spring容器服务。我们可以通过类

中的下面的方法获取当前的applicationContext实例
public void setApplicationContext(ApplicationContext context) throws BeansException.