Весной, если компонент реализует 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" />
Здесь bean-компонент SpringContextUtil
не включает свойство applicationContext
. Я предполагаю, что при инициализации Spring bean это свойство устанавливается. Но как это сделать? Как вызывается метод setApplicationContext
?
Ответы:
Когда 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;
источник
ApplicationContext
, то его нельзя получитьApplicationContextAware instance
ни из одного другого. Потому чтоApplicationContextAware instance
получает bean-компонент из того жеapplicationContext
объекта, что и введенный.Исходный код Spring, объясняющий, как работает ApplicationContextAware,
когда вы используете класс
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
In
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)); ...........
Когда Spring инициализирует bean-компонент в
AbstractAutowireCapableBeanFactory
методеinitializeBean
, вызываетсяapplyBeanPostProcessorsBeforeInitialization
для реализации пост-процесса 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); } } }
источник
приведенный выше фрагмент взят с веб-сайта документации Spring https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ApplicationContextAware.html .
Итак, казалось, что он вызывается при запуске контейнера Spring, если вы хотите что-то сделать в это время.
У него есть только один метод для установки контекста, так что вы получите контекст и сделаете что-нибудь, что уже в контексте, я думаю.
источник
ApplicationContextAware Интерфейс, текущий контекст приложения, через который вы можете вызывать службы контейнера Spring. Мы можем получить текущий экземпляр applicationContext, введенный нижеприведенным методом в классе
public void setApplicationContext(ApplicationContext context) throws BeansException.
источник