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时,它会查找一些接口,如ApplicationContextAware
和InitializingBean
。 如果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/