Wiosną, jeśli fasola się zaimplementuje ApplicationContextAware
, może uzyskać dostęp do applicationContext
. Dlatego jest w stanie uzyskać inne ziarna. na przykład
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext context) throws BeansException {
applicationContext = context;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
}
Następnie SpringContextUtil.getApplicationContext.getBean("name")
można uzyskać „nazwę” fasoli.
Aby to zrobić, należy umieścić to SpringContextUtil
wewnątrz applications.xml
np
<bean class="com.util.SpringContextUtil" />
Tutaj fasola SpringContextUtil
nie obejmuje właściwości applicationContext
. Wydaje mi się, że podczas inicjalizacji fasoli wiosennej ta właściwość jest ustawiona. Ale jak to się robi? Jak setApplicationContext
wywoływana jest metoda ?
Odpowiedzi:
Gdy wiosna tworzy instancję, szuka kilku interfejsów, takich jak
ApplicationContextAware
iInitializingBean
. Jeśli zostaną znalezione, wywoływane są metody. Np. (Bardzo uproszczone)Class<?> beanClass = beanDefinition.getClass(); Object bean = beanClass.newInstance(); if (bean instanceof ApplicationContextAware) { ((ApplicationContextAware) bean).setApplicationContext(ctx); }
Zwróć uwagę, że w nowszej wersji może być lepiej użyć adnotacji, niż implementować interfejsy specyficzne dla sprężyny. Teraz możesz po prostu użyć:
@Inject // or @Autowired private ApplicationContext ctx;
źródło
ApplicationContext
, to nie można jej również pobraćApplicationContextAware instance
. PonieważApplicationContextAware instance
dostaje ziarno z tego samegoapplicationContext
przedmiotu, co wstrzyknięty.Kod źródłowy Spring wyjaśniający, jak ApplicationContextAware działa,
gdy używasz
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
In
AbstractApplicationContext
class,refresh()
metoda ma następujący kod:// Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory);
wprowadź tę metodę,
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
doda ApplicationContextAwareProcessor do 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)); ...........
Gdy wiosna zainicjuje bean
AbstractAutowireCapableBeanFactory
w metodzieinitializeBean
, wywołajapplyBeanPostProcessorsBeforeInitialization
aby zaimplementować proces post bean. proces obejmuje wstrzyknięcie 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; }
gdy BeanPostProcessor implementuje Object, aby wykonać metodę postProcessBeforeInitialization, na przykład
ApplicationContextAwareProcessor
dodaną wcześniej.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); } } }
źródło
powyżej pochodzi z witryny Spring doc https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ApplicationContextAware.html .
Wydawało się więc, że został wywołany, gdy kontener Spring został uruchomiony, jeśli chcesz coś zrobić w tym czasie.
Ma tylko jedną metodę ustawiania kontekstu, więc myślę, że dostaniesz kontekst i zrobisz coś, co jest już w kontekście.
źródło
ApplicationContextAware Interface, bieżący kontekst aplikacji, za pomocą którego można wywoływać usługi kontenera sprężynowego. Możemy pobrać bieżącą instancję applicationContext wstrzykniętą poniższą metodą w klasie
public void setApplicationContext(ApplicationContext context) throws BeansException.
źródło