ApplicationContextAware在春季如何工作?

2022-08-31 11:33:02

在春天,如果一个bean实现了,那么它能够访问.因此,它能够获得其他豆类。例如:ApplicationContextAwareapplicationContext

public class SpringContextUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;     

    public void setApplicationContext(ApplicationContext context) throws BeansException {
      applicationContext = context;
    }

    public static ApplicationContext getApplicationContext() {
      return applicationContext;
    }
}

然后可以得到豆子的“名字”。SpringContextUtil.getApplicationContext.getBean("name")

为此,我们应该将其放在 ,例如SpringContextUtilapplications.xml

<bean class="com.util.SpringContextUtil" />

在这里,豆子不包括属性。我猜当弹簧豆初始化时,这个属性是设置的。但这是如何做到的呢?如何调用该方法?SpringContextUtilapplicationContextsetApplicationContext


答案 1

当 spring 实例化 Bean 时,它会查找几个接口,如 和 。如果找到它们,则调用这些方法。例如(非常简化)ApplicationContextAwareInitializingBean

Class<?> beanClass = beanDefinition.getClass();
Object bean = beanClass.newInstance();
if (bean instanceof ApplicationContextAware) {
    ((ApplicationContextAware) bean).setApplicationContext(ctx);
}

请注意,在较新版本中,最好使用注释,而不是实现特定于spring的接口。现在,您可以简单地使用:

@Inject // or @Autowired
private ApplicationContext ctx;

答案 2

Spring源代码解释了当你使用
In class时AppplicationContextAware是如何工作的
,该方法有以下代码:ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");AbstractApplicationContextrefresh()

// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

输入此方法,会将 ApplicationContextAwareProcessor 添加到 AbstractrBeanFactory。beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

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 在 中初始化 Bean 时,在方法中调用实现 Bean 的后处理。该过程包括注入应用程序Context。AbstractAutowireCapableBeanFactoryinitializeBeanapplyBeanPostProcessorsBeforeInitialization

@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方法时,例如之前添加的方法。ApplicationContextAwareProcessor

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);
            }
        }
    }

推荐