title: Spring回调接口Aware-源码分析
date: 2020-04-24 21:37:27
tags:
Spring
提供了一种机制,让bean
在实例化的时候,能够感知(获取)容器中的一些组件,即Aware接口回调的方式。这种机制一般是Spring
框架内部使用。
Aware | z作用 |
---|---|
BeanFactoryAware | 获取当前 BeanFactory,这样可以调用容器的服务 |
ApplicationContextAware | t同BeanFactory |
MessageSourceAware | 获取 Message Source 相关文本信息 |
ApplicationEventPublisherAware | 发布事件 |
ResourceLoaderAware | 获取资源加载器,这样获取外部资源文件 |
BeanNameAware | 获取容器中 Bean 的名称 |
@Component
public class AwareTest implements ApplicationContextAware , BeanNameAware {
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("取得applicationContext。。。。");
}
public void setBeanName(String name) {
System.out.println(name);
}
}
在这些Aware中,底层实现主要分为两种:
invokeAwareMethods(beanName, bean);
BeanPostProcessor
(1)invokeAwareMethods(beanName, bean);
在创建bean
的核心方法initializeBean
中,创建好bean
后,都会先调用invokeAwareMethods(beanName, bean);
,再进行初始化。
若这个bean
为一个Aware
,就去尝试调用一些回调方法。
在这个方法中,有三种Aware
会在这个方法中被调用:BeanNameAware
、BeanClassLoaderAware
、BeanFactoryAware
。
//
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
(2)BeanPostProcessor
其余的Aware
是由BeanPostProcessor
来实现的,xxxAware
都有一个xxxAwareProcessor
与之对应,例如ApplicationAware
-----ApplicationAwareProcessor
。
在Spring Bean的创建初始化过程–源码分析中,我们已经说过beanPostProcessor
的前置处理都是在applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)
中被一一执行。
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
//调用postProcessBeforeInitialization
Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
以ApplicationAwareProcessor
为例,经过一些安全验证,最终会调用invokeAwareInterfaces(bean)
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
逻辑也很简单,判断这个Aware
是哪个Aware
,就强制转换调用。
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(this.embeddedValueResolver);
}
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);
}
}
}