Au printemps, si un bean implémente ApplicationContextAware
, il est alors en mesure d'accéder à applicationContext
. Par conséquent, il est capable d'obtenir d'autres haricots. par exemple.
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext context) throws BeansException {
applicationContext = context;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
}
Alors SpringContextUtil.getApplicationContext.getBean("name")
peut obtenir le "nom" du haricot.
Pour ce faire, nous devrions placer ceci SpringContextUtil
dans le applications.xml
, Par exemple.
<bean class="com.util.SpringContextUtil" />
Ici le bean SpringContextUtil
n'inclut pas la propriété applicationContext
. J'imagine que lorsque le haricot printanier s'initialise, cette propriété est définie. Mais comment est-ce que c'est fait? Comment la méthode setApplicationContext
est-elle appelée?
Lorsque le printemps instancie des haricots, il recherche quelques interfaces comme ApplicationContextAware
et InitializingBean
. Si elles sont trouvées, les méthodes sont appelées. Par exemple. (très simplifié)
Class<?> beanClass = beanDefinition.getClass();
Object bean = beanClass.newInstance();
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(ctx);
}
Notez que dans les versions plus récentes, il peut être préférable d’utiliser des annotations plutôt que de mettre en œuvre des interfaces spécifiques à un ressort. Maintenant, vous pouvez simplement utiliser:
@Inject // or @Autowired
private ApplicationContext ctx;
code source Spring pour expliquer le fonctionnement de ApplicationContextAware
lorsque vous utilisez ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Dans AbstractApplicationContext
class, la méthode refresh()
a le code suivant:
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
entrez cette méthode, beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
ajoutera 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));
...........
Lorsque spring initialise le bean dans AbstractAutowireCapableBeanFactory
, dans la méthode initializeBean
, appelez applyBeanPostProcessorsBeforeInitialization
pour implémenter le post-traitement du bean. le processus comprend l'injection de l'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;
}
lorsque BeanPostProcessor implémente Object pour exécuter la méthode postProcessBeforeInitialization, par exemple ApplicationContextAwareProcessor
ajouté précédemment.
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);
}
}
}