Spring Aware
一个空标记接口,表示 bean 可以通过接口定义的回调方法,获取相应的 Spring容器对象 对bean进行处理
源码分析
1. 首先在 实现 EnvironmemtAware接口对象 中的 setEnvironment(Environment environment)方法 打断点,通过堆栈,查看具体 Aware接口 的调用执行顺序,进行源码分析
通过堆栈分析,我们可以知道,Aware接口 的调用点有两处
a. AbstractCapableBeanFactory工厂类 的 initializeBean方法 里的 invokeAwareMethods(beanName, bean)方法
b. ApplicationContextAwareProcessor后处理器 的 postProcessBeforeInitialization方法里 invokeAwareInterfaces(bean)方法
第一个调用点是 AbstractCapableBeanFactory工厂类 的 initializeBean方法 里的 invokeAwareMethods(beanName, bean)方法,下面我们对该方法进行分析
该方法处理 Aware接口 的顺序:BeanNameAware -> BeanClassLoaderAware -> BeanFactoryAware
1. 进入 initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd)方法
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// 安全管理器模式
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareMethods(beanName, bean);
return null;
}, this.getAccessControlContext());
} else {
// Aware接口 的第一个调用点
this.invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 遍历所有的后处理器,得到ApplicationContextAwareProcessor后处理器,然后执行相应Aware对象处理
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
try {
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
2. 进入 this.invokeAwareMethods(beanName, bean)方法
// 这是对 Aware接口 的直接方法调用
private void invokeAwareMethods(String beanName, Object bean) {
// 如果bean是Aware类型(这里指的是实现Aware接口)
if (bean instanceof Aware) {
// 如果bean是BeanNameAware类型
if (bean instanceof BeanNameAware) {
// 设置bean名称
((BeanNameAware)bean).setBeanName(beanName);
}
// 如果bean是BeanClassLoaderAware类型
if (bean instanceof BeanClassLoaderAware) {
// 获取类加载器
ClassLoader bcl = this.getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);
}
}
// 如果bean是BeanFactoryAware类型
if (bean instanceof BeanFactoryAware) {
// 获取beanFactory工厂
((BeanFactoryAware)bean).setBeanFactory(this);
}
}
}
第二个调用点是 ApplicationContextAwareProcessor后处理器 的 postProcessBeforeInitialization方法 里的 invokeAwareInterfaces(bean)方法,下面我们来具体分析不同类型的Aware具体加载了什么
该方法处理 Aware接口 的顺序:EnvironmentAware -> EmbeddedValueResolverAware -> ResourceLoaderAware ->ApplicationEventPublisherAware -> MessageSourceAware -> ApplicationContextAware
1. 进入 postProcessBeforeInitialization(Object bean, String beanName)方法
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 对bean类型进行判断
if (!(bean instanceof EnvironmentAware) && !(bean instanceof EmbeddedValueResolverAware) && !(bean instanceof ResourceLoaderAware) && !(bean instanceof ApplicationEventPublisherAware) && !(bean instanceof MessageSourceAware) && !(bean instanceof ApplicationContextAware)) {
return bean;
} else {
AccessControlContext acc = null;
if (System.getSecurityManager() != null) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
// 安全管理器模式
if (acc != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareInterfaces(bean);
return null;
}, acc);
} else {
this.invokeAwareInterfaces(bean);
}
return bean;
}
}
2. 进入 this.invokeAwareInterfaces(bean)方法
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EnvironmentAware) {
// 获取 Environment环境变量,可以通过 Environment环境变量 获取属性
((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
// 获取 Spring容器 加载的 properties文件 里面相应的属性值
((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) {
// 获取 ApplicationContext上下文容器
((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
}
}
- End -(转载请注明出处)
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。