Java ApplicationContextAware在春季如何工作?

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" /&

在春季,如果bean实现了
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);
            }
        }
    }