Spring的感知能力 Aware
在 Spring 框架中有一个 org.springframework.beans.factory.Aware 接口,
Aware 是感知感应的意思,那么此接口的作用就是为 Spring 中的 bean 提供了感知外界的能力。
Aware接口本身只是一个标记接口,Spring 中提供了一系列具有具体感知能力的接口,它们都继承自 Aware 接口,
部分如下:
LoadTimeWeaverAware:加载 Spring Bean 时织入第三方模块,如AspectJ
BeanClassLoaderAware:加载 Spring Bean 的类加载器
BootstrapContextAware:资源适配器 BootstrapContext,如JCA,CCI
ResourceLoaderAware:底层访问资源的加载器
BeanFactoryAware:声明 BeanFactory
PortletConfigAware:PortletConfig
PortletContextAware:PortletContext
ServletConfigAware:ServletConfig
ServletContextAware:ServletContext
MessageSourceAware:国际化
ApplicationEventPublisherAware:应用事件
NotificationPublisherAware:JMX通知
BeanNameAware:声明 Spring Bean 的名字
此处以 BeanNameAware 举例,其内部包含了一个 setBeanName 方法,所以当一个 bean 继承了此接口,并定义一个 beanName 的属性,
则在 Spring 容器初始化这个 bean 的时候,会调用这个 setBeanName 方法,注入这个 beanName。
不同的 Aware 注入对应的外界信息的时机是不一样的,具体也分为两类:
1. BeanNameAware/BeanClassLoaderAware/BeanFactoryAware
这三类 Aware 生效的时机是在容器创建 bean 的最后一步完成,具体的调用顺序如下:
getBean(String beanName)
doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
getSingleton(String beanName, ObjectFactory<?> singletonFactory)
在 getSingleton 会回调
createBean(String beanName, RootBeanDefinition mbd, Object[] args)
doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd)
最终在 initializeBean 内会调用如下方法,此处分别调用了对应的 setXXX 方法,外部信息得以注入
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
2. LoadTimeWeaverAware/ApplicationContextAware/ServletContextAware/MessageSourceAware 等
这一类 Aware 是通过 BeanPostProcessor bean后置处理器实现外部信息注入的。
同样在上述的 initializeBean 方法内会调用如下方法
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 的 postProcessBeforeInitialization 方法,而 ApplicationContextAwareProcessor 是默认注册到容器内的,其 postProcessBeforeInitialization 方法内会调用如下方法:
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);
}
}
}
所以 bean 只要继承了 EnvironmentAware,ResourceLoaderAware 就具备相应的感知能力。
Spring的感知能力 Aware的更多相关文章
- 手写Spring,定义标记类型Aware接口,实现感知容器对象
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 同事写的代码,我竟丝毫看不懂! 大佬的代码,就像 "赖蛤蟆泡青蛙,张的丑玩 ...
- 想减少代码量,快设置一个有感知的 Aware Spring Bean
摘要:正常情况下,Spring 中的 Bean 对 Spring 是无感知的,Spring 框架提供了这种扩展能力,能让一个 bean 成为有感知的. 本文分享自华为云社区<有感知的 Aware ...
- spring源码:Aware接口(li)
一.spring容器中的aware接口介绍 Spring中提供了各种Aware接口,比较常见的如BeanFactoryAware,BeanNameAware,ApplicationContextAwa ...
- spring源码:Aware接口
一.spring容器中的aware接口介绍 Spring中提供了各种Aware接口,比较常见的如BeanFactoryAware,BeanNameAware,ApplicationContextAwa ...
- Spring InitializingBean 接口以及Aware接口实现的原理
关于Spring InitializingBean 接口以及Aware接口实现的其实都在 第11步中: finishBeanFactoryInitialization() 方法中完成了3部分的内容: ...
- Spring扩展点之Aware接口族
引言 Spring中提供了各种Aware接口,方便从上下文中获取当前的运行环境,比较常见的几个子接口有:BeanFactoryAware,BeanNameAware,ApplicationContex ...
- Spring扩展之五:Aware接口等
ApplicationContextAwareProcessor 1.介绍 ApplicationContextAwareProcessor是一个Spring内部工具,它实现了接口BeanPostPr ...
- spring扩展点之四:Spring Aware容器感知技术,BeanNameAware和BeanFactoryAware接口,springboot中的EnvironmentAware
aware:英 [əˈweə(r)] 美 [əˈwer] adj.意识到的;知道的;觉察到的 XXXAware在spring里表示对XXX感知,实现XXXAware接口,并通过实现对应的set-XXX ...
- 对Spring aware理解
aware翻译过来时就是意识到,我对他的理解就是spring的感知器.是不是很诡异这个名字起得^_^ 先来看看aware接口的结构 spring提供了许多的aware,Aware.java也只是做一个 ...
随机推荐
- 知识点总结 HTML+CSS部分
1.html+css经典布局 ①左列定宽,右列自适应 .left{width:100px;float:left;} .right{overflow:hidden;} ②两列顶宽,中栏自适应 .left ...
- Web协议详解与抓包实战:HTTP1协议-详解请求行(2)
一.请求行一 二.请求行二 三.请求行三 四.常见方法(RFC7231) 实际测试截图 五.用于文档管理的 WEBDAV 方法(RFC2518) 六.WEBDAV 验证环境 1.登录 2.Wire ...
- [LeetCode] 673. Number of Longest Increasing Subsequence 最长递增序列的个数
Given an unsorted array of integers, find the number of longest increasing subsequence. Example 1: I ...
- shell脚本中“$?”标记的用途是什么?
在写一个shell脚本时,如果你想要检查前一命令是否执行成功,在if条件中使用“$?”可以来检查前一命令的结束状态.
- 关于ProxmoxVE
1) PVE简介 PVE是Proxmox Virtual Environment(Proxmox虚拟化环境,也通常简称为Proxmox VE)的简称,它是基于QEMU/KVM和LXC的开源服务器虚拟化 ...
- Intellij IDEA使用一 创建javaweb项目并配置tomcat
一.新建Java web项目 参考:https://blog.csdn.net/chengtengfei352/article/details/79211619 1.点击创建新项目 2. 3.crea ...
- Windows下MySQL安装流程,8.0以上版本ROOT密码报错及修改
官网下载MySQL安装后,解压,添加环境变量,以管理员方式运行cmd,运行以下命令 mysqld --initialize --console mysqld -install net start my ...
- Azure Devops (VSTS) Extensions 开发小记
我在使用tfx-cli打包Azure Devops插件时,输出了很黄很黄很亮瞎眼的(尤其是在Visual Studio Code采用了Dark Black Theme的情况下)警告warning: P ...
- 【C++】Debug模式和Release模式的区别
VS中的程序有两种编译模式:Debug模式和Release模式. Debug通常称为调试版本,通过一系列编译选项的配合,编译结果通常包含调试信息,而且不做任何优化,以为开发人员提供强大的应用程序调试能 ...
- [转帖]PG的时间函数使用整理如下
PG的时间函数使用整理如下 https://blog.csdn.net/dahuzix/article/details/48576945 1.获取系统时间函数 -- :: -- :: -- :: 2. ...