Как ApplicationContextAware работает в Spring?
В spring, если bean реализует ApplicationContextAware
, тогда он может получить доступ к applicationContext
. Поэтому он может получить другой beans.
например
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 ".
Чтобы сделать это, мы должны поместить этот SpringContextUtil
внутри applications.xml
, например.
<bean class="com.util.SpringContextUtil" />
Здесь bean SpringContextUtil
не включает свойство applicationContext
. Я думаю, когда spring bean initialize, это свойство установлено. Но как это делается? Как вызывается метод setApplicationContext
?
Ответы
Ответ 1
Когда spring создает экземпляр beans, он ищет пару интерфейсов, таких как ApplicationContextAware
и InitializingBean
. Если они найдены, методы вызываются. Например. (очень упрощенный)
Class<?> beanClass = beanDefinition.getClass();
Object bean = beanClass.newInstance();
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(ctx);
}
Обратите внимание, что в более новой версии лучше использовать аннотации, а не использовать spring -специфические интерфейсы. Теперь вы можете просто использовать:
@Inject // or @Autowired
private ApplicationContext ctx;
Ответ 2
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 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 инициализируется bean в AbstractAutowireCapableBeanFactory
,
в методе initializeBean
вызовите applyBeanPostProcessorsBeforeInitialization
, чтобы реализовать процесс post 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);
}
}
}
Ответ 3
Интерфейс ApplicationContextAware, текущий контекст приложения, через который вы можете вызвать службы контейнера spring. Мы можем получить текущий экземпляр applicationContext, введенный ниже методом в классе
public void setApplicationContext(ApplicationContext context) throws BeansException.
Чтобы лучше понять, как использовать ApplicationContextAware, обратитесь к этому http://www.javapointer.com/spring/spring-core/how-to-use-applicationcontextaware-in-spring/