En primavera, si un frijol se implementa ApplicationContextAware
, entonces puede acceder al archivo applicationContext
. Por lo tanto, puede obtener otros granos. p.ej
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext context) throws BeansException {
applicationContext = context;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
}
Entonces SpringContextUtil.getApplicationContext.getBean("name")
puede obtener el "nombre" del bean.
Para hacer esto, debemos poner esto SpringContextUtil
dentro de applications.xml
, por ejemplo
<bean class="com.util.SpringContextUtil" />
Aquí el frijol SpringContextUtil
no incluye la propiedad applicationContext
. Supongo que cuando se inicializa el frijol de primavera, se establece esta propiedad. Pero, ¿cómo se hace esto? ¿Cómo setApplicationContext
se llama al método ?
Respuestas:
Cuando spring instancia beans, busca un par de interfaces como
ApplicationContextAware
yInitializingBean
. Si se encuentran, se invocan los métodos. Ej. (Muy simplificado)Class<?> beanClass = beanDefinition.getClass(); Object bean = beanClass.newInstance(); if (bean instanceof ApplicationContextAware) { ((ApplicationContextAware) bean).setApplicationContext(ctx); }
Tenga en cuenta que en la versión más reciente puede ser mejor usar anotaciones, en lugar de implementar interfaces específicas de Spring. Ahora puedes simplemente usar:
@Inject // or @Autowired private ApplicationContext ctx;
fuente
ApplicationContext
, tampoco se puede obtener deApplicationContextAware instance
ninguno. PorqueApplicationContextAware instance
obtiene un frijol del mismoapplicationContext
objeto que el inyectado.Spring código fuente para explicar cómo funciona ApplicationContextAware
cuando usa
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
En
AbstractApplicationContext
clase, elrefresh()
método tiene el siguiente código:// Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory);
ingrese este método,
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
agregará ApplicationContextAwareProcessor a 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)); ...........
Cuando spring initialize bean in
AbstractAutowireCapableBeanFactory
, en el métodoinitializeBean
, llameapplyBeanPostProcessorsBeforeInitialization
para implementar el proceso de post de bean. el proceso incluye inyectar el 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; }
cuando BeanPostProcessor implemente Object para ejecutar el método postProcessBeforeInitialization, por ejemplo,
ApplicationContextAwareProcessor
el agregado antes.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); } } }
fuente
arriba está extraído del sitio web de Spring doc https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ApplicationContextAware.html .
Por lo tanto, parece que se invoca cuando se inicia el contenedor Spring, si desea hacer algo en ese momento.
Solo tiene un método para establecer el contexto, por lo que obtendrá el contexto y hará algo para algo ahora ya en el contexto, creo.
fuente
ApplicationContextAware Interface, el contexto actual de la aplicación, a través del cual puede invocar los servicios de contenedor de primavera. Podemos obtener la instancia de applicationContext actual inyectada por el método siguiente en la clase
public void setApplicationContext(ApplicationContext context) throws BeansException.
fuente