with - spring batch processing in java
¿Cómo funciona ApplicationContextAware en Spring? (3)
ApplicationContextAware Interface, el contexto actual de la aplicación, a través del cual puede invocar los servicios del contenedor de primavera. Podemos obtener la instancia actual de ApplicationContext inyectada por el método de abajo en la clase
public void setApplicationContext(ApplicationContext context) throws BeansException.
En primavera, si un bean implementa ApplicationContextAware
, entonces puede acceder al applicationContext
. Por lo tanto, es capaz de obtener otros frijoles. 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 este SpringContextUtil
dentro de las applications.xml
, por ejemplo
<bean class="com.util.SpringContextUtil" />
Aquí, el bean SpringContextUtil
no incluye la propiedad applicationContext
. Supongo que cuando Spring Bean se inicializa, esta propiedad está configurada. Pero, ¿cómo se hace esto? ¿Cómo se llama el método setApplicationContext
?
Cuando Spring crea instancias de beans, busca un par de interfaces como ApplicationContextAware
e InitializingBean
. 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 una versión más nueva, puede ser mejor usar anotaciones, en lugar de implementar interfaces específicas para resortes. Ahora puedes simplemente usar:
@Inject // or @Autowired
private ApplicationContext ctx;
Código fuente de Spring para explicar cómo funciona ApplicationContextAware
cuando usa ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
En la clase AbstractApplicationContext
, el método refresh()
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 el bean initialize bean en AbstractAutowireCapableBeanFactory
, en el método initializeBean
, llame a applyBeanPostProcessorsBeforeInitialization
para implementar el proceso posterior del 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 implementa Object para ejecutar el método postProcessBeforeInitialization, por ejemplo ApplicationContextAwareProcessor
que se agregó 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);
}
}
}