ApplicationContextAware在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如何被调用?

当spring实例化bean时,它会查找一些接口,如ApplicationContextAwareInitializingBean 。 如果find了,则调用这些方法。 例如(非常简化)

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

请注意,在新版本中,使用注释可能会更好,而不是实现弹簧专用接口。 现在你可以简单地使用:

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

input这个方法, 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实现Objectto时执行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); } } } 

ApplicationContextAware接口,当前的应用程序上下文,通过它可以调用spring容器服务。 我们可以通过下面的方法在类中注入当前的applicationContext实例

  public void setApplicationContext(ApplicationContext context) throws BeansException. 

为了更好地了解如何使用ApplicationContextAware,请参考这个http://www.javapointer.com/spring/spring-core/how-to-use-applicationcontextaware-in-spring/