Java ApplicationContextAware在春季如何工作?
在春季,如果bean实现了Java ApplicationContextAware在春季如何工作?,java,spring,Java,Spring,在春季,如果bean实现了ApplicationContextAware,那么它就能够访问applicationContext。因此,它可以得到其他豆类。 e、 g 然后springcontexttil.getApplicationContext.getBean(“name”)可以获取bean“name” 为此,我们应该将这个SpringContextUtil放在applications.xml中,例如 <bean class="com.util.SpringContextUtil" /&
ApplicationContextAware
,那么它就能够访问applicationContext
。因此,它可以得到其他豆类。
e、 g
然后springcontexttil.getApplicationContext.getBean(“name”)
可以获取bean“name”
为此,我们应该将这个SpringContextUtil
放在applications.xml
中,例如
<bean class="com.util.SpringContextUtil" />
这里bean
SpringContextUtil
不包括属性applicationContext
。我猜当Springbean初始化时,这个属性被设置。但这是如何做到的?方法setApplicationContext
是如何被调用的?当spring实例化bean时,它会寻找两个接口,如ApplicationContextAware
和InitializingBean
。如果找到它们,则调用这些方法。例如(非常简化)
ApplicationContextAware接口,当前应用程序上下文,通过它可以调用spring容器服务。我们可以在类中获得由下面的方法注入的当前applicationContext实例
public void setApplicationContext(ApplicationContext context) throws BeansException.
解释ApplicationContextAware如何工作的Spring源代码
当您使用
ApplicationContext context=new ClassPathXmlApplicationContext(“ApplicationContext.xml”)代码>
在AbstractApplicationContext
类中,refresh()
方法具有以下代码:
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
输入此方法,beanFactory.addBeanPostProcessor(新应用程序ContextawarProcessor(this))代码>将向AbstractrBeanFactory添加ApplicationContextawarReprocessor
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在AbstractAutowireCapableBeanFactory中初始化bean时,
在方法initializeBean
中,在初始化之前调用applybeanpostprocessors
以实现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实现object以执行postProcessBeforeInitialization方法时,例如前面添加的ApplicationContextawareReprocessor
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);
}
}
}
接口,该接口将由任何希望收到其运行的ApplicationContext通知的对象实现
以上内容摘自SpringDoc网站
所以,它似乎是在Spring容器启动时调用的,如果您当时想做些什么的话
它只有一种设置上下文的方法,因此您将获得上下文并在上下文中对某事物做一些事情。非常感谢,这就是我想要的!也许我需要阅读一些spring代码来理解spring是如何工作的。在大多数情况下使用@Autowired更好,但在其他情况下,这可能不起作用,例如,当您有一个“@Component”是单例,但您需要注入一个具有会话作用域的bean时。由于依赖项是在应用程序上下文创建中自动连接的,因此不会真正注入会话bean,通过对应用程序上下文的引用,您可以通过编程方式检索会话bean,从而正确返回会话bean实例。我希望Spring会注入一个动态生成的代理类—这样的类具有应用程序范围,但当被访问时,它会委托给会话范围实例,如果没有绑定到当前运行的请求,则引发异常thread@raspacorp如果无法从注入的ApplicationContext
获取sesson作用域bean,则也无法从ApplicationContextAware实例
获取它。因为ApplicationContextAware实例
从与注入的对象相同的applicationContext
对象中获取bean。Spring很神奇。拥抱魔法
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));
...........
@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;
}
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);
}
}
}