Как работает ApplicationContextAware весной?
весной, если Боб реализует 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") может получить Боб "имя".
чтобы сделать это, мы должны поставить это SpringContextUtil внутри applications.xml, например,
<bean class="com.util.SpringContextUtil" />
вот Боб SpringContextUtil не содержат свойство applicationContext. Я думаю, когда spring bean инициализируется, это свойство устанавливается. Но как это делается? Как работает метод setApplicationContext тебе позвонили?
3 ответов:
когда spring создает экземпляры beans, он ищет несколько интерфейсов, таких как
ApplicationContextAwareиInitializingBean. Если они найдены, то вызываются методы. Например (очень упрощенный)Class<?> beanClass = beanDefinition.getClass(); Object bean = beanClass.newInstance(); if (bean instanceof ApplicationContextAware) { ((ApplicationContextAware) bean).setApplicationContext(ctx); }обратите внимание, что в более новой версии может быть лучше использовать аннотации, а не реализовывать интерфейсы spring-specific. Теперь вы можете просто использовать:
@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);введите этот метод,
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)); ...........когда весна инициализирует боб в
AbstractAutowireCapableBeanFactory, в методе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 реализует объект для выполнения метода 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.
Comments