【spring源码分析】IOC容器初始化——查漏补缺(一)
前言:在【spring源码分析】IOC容器初始化(十一)中提到了初始化bean的三个步骤:
- 激活Aware方法。
- 后置处理器应用(before/after)。
- 激活自定义的init方法。
这里我们就来看下Spring是如何激活Aware方法的。
Aware是什么
Aware是一个空接口,包路径为:org.springframework.beans.factory.Aware,它具有标识作用,实现了该接口的bean具有被Spring容器通知的能力,通知的方式采用回调的方式。
由于Aware是一个空接口,实际的方法签名由各个子类来确定,其该接口通常只会有一个接收单参数的set方法,该set方法的命名方式为set+去掉接口中的Aware后缀,即:setxxx(),那Spring中是如何处理实现Aware接口的bean的呢。在invokeAwareMethods方法中可以看到如下代码:
// AbstractAutowireCapableBeanFactory
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
// BeanNameAware
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
// BeanClassLoaderAware
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
// BeanFactoryAware
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
分析:
首先判断bean是否实现了Aware接口,如果是则调用实例的setXXX()方法给实例设置xxx属性,在invokeAwareMethods方法中,主要处理BeanNameAware、BeanClassLoaderAware、BeanFactoryAware三种接口,也从侧面证实了Spring只会处理实现了这三种接口中任意一个的bean实例。
Aware示例演示
下面就演示Spring是如何处理实现这三个接口的bean的:
public class UserDefinedAware implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware { private String name;
private ClassLoader classLoader;
private BeanFactory beanFactory; @Override
public void setBeanName(String name) {
System.out.println("调用了 BeanNameAware 的 setBeanName方法");
this.name = name;
} @Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("调用了 BeanClassLoader 的 setBeanClassLoader 方法");
this.classLoader = classLoader;
} @Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("调用了 BeanFactoryAware 的 setBeanFactory 方法");
this.beanFactory = beanFactory;
} public void showMsg() {
System.out.println("beanName=" + this.name);
System.out.println("classLoader=" + this.classLoader.getClass());
System.out.println("是否为单例=" + beanFactory.isSingleton(this.name));
}
}
测试方法如下:
/**
* Aware接口演示
*/
@Test
public void awareTest() {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:com/dev/config/aware/aware.xml");
UserDefinedAware userDefinedAware = context.getBean(UserDefinedAware.class);
userDefinedAware.showMsg();
}
输出结果如下:
Aware总结
从以上示例基本上可以了解 Aware接口 真正的含义:感知,其实是Spring容器在初始化主动检测当前bean是否实现了Aware接口,如果实现了则回调其set方法将相应的参数设置给该bean,这个时候该bean就从Spring容器中取得了相应的资源。所以Aware接口的作用就是让实现该接口的bean能从Spring容器中取得相应的资源。这里如name、ClassLoader、beanFactory。
下面列出一些常用的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的名字
by Shawn Chen,2019.04.29,晚上。
【spring源码分析】IOC容器初始化——查漏补缺(一)的更多相关文章
- 【spring源码分析】IOC容器初始化——查漏补缺(五)
前言:我们知道在Spring中经常使用配置文件的形式对进行属性的赋值,那配置文件的值是怎么赋值到属性上的呢,本文将对其进行分析. 首先了解一个类:PropertySourcesPlaceholderC ...
- 【spring源码分析】IOC容器初始化——查漏补缺(二)
前言:在[spring源码分析]IOC容器初始化(八)中多次提到了前置处理与后置处理,本篇文章针对此问题进行分析.Spring对前置处理或后置处理主要通过BeanPostProcessor进行实现. ...
- 【spring源码分析】IOC容器初始化——查漏补缺(四)
前言:在前几篇查漏补缺中,其实我们已经涉及到bean生命周期了,本篇内容进行详细分析. 首先看bean实例化过程: 分析: bean实例化开始后 注入对象属性后(前面IOC初始化十几篇文章). 检查激 ...
- SPRING源码分析:IOC容器
在Spring中,最基本的IOC容器接口是BeanFactory - 这个接口为具体的IOC容器的实现作了最基本的功能规定 - 不管怎么着,作为IOC容器,这些接口你必须要满足应用程序的最基本要求: ...
- 【spring源码分析】IOC容器初始化——查漏补缺(三)
前言:本文分析InitializingBean和init-method方法,其实该知识点在AbstractAutowireCapableBeanFactory#initializeBean方法中有所提 ...
- Spring源码解析-ioc容器的设计
Spring源码解析-ioc容器的设计 1 IoC容器系列的设计:BeanFactory和ApplicatioContext 在Spring容器中,主要分为两个主要的容器系列,一个是实现BeanFac ...
- spring源码分析---IOC(1)
我们都知道spring有2个最重要的概念,IOC(控制反转)和AOP(依赖注入).今天我就分享一下spring源码的IOC. IOC的定义:直观的来说,就是由spring来负责控制对象的生命周期和对象 ...
- spring 源码之 ioc 容器的初始化和注入简图
IoC最核心就是两个过程:IoC容器初始化和IoC依赖注入,下面通过简单的图示来表述其中的关键过程:
- Spring源码阅读-IoC容器解析
目录 Spring IoC容器 ApplicationContext设计解析 BeanFactory ListableBeanFactory HierarchicalBeanFactory Messa ...
随机推荐
- python——vs2017安装python库时,提示pip指令问题。
需要跟新pip指令 方法: 第一步:打开vs2017 后新建一个python 文件 后面如图 点击红色部分 2.在框中输入pip之后更新即可 如图 3.问题解决 倘若还有问题 欢迎分享
- GIL计算python 2 和 python 3 计算密集型
首先我画了一张图来表示GIL运行的方式: Python 3执行如下计算代码:#-*-conding:utf-8-*-import threading import timedef add(): n = ...
- __module__ 和 __class__
__module__ 查看当前方法来之于那个文件 __class__ 查看当前方法来之于那个类
- 大数据入门到精通12--spark dataframe 注册成hive 的临时表
一.获得最初的数据并形成dataframe val ny= sc.textFile("data/new_york/")val header=ny.firstval filterNY ...
- JS中的事件(对象,冒泡,委托,绑定)
- 事件,是文档或浏览器窗口中发生的一些特定的交互瞬间,JS与HTML之间的交互是通过事件实现的 对于web应用来说,有下面这些代表性事件:点击事件,鼠标移动,按下键盘等等 - 事件,是用户和浏览器之 ...
- mysql 报错You can't specify target table 'wms_cabinet_form' for update in FROM clause
这个错误是说从t表select出来的无法又更新t表. 可以在select的时候先取个别名,弄个临时表即可.
- input date 支持placeholder属性
第一种解决方法:IE,火狐浏览器,不支持input date的日历功能,火狐支持日历功能 ie,火狐,谷歌显示placeholder属性 css代码 #dateofday:before{ col ...
- [leetcode]6. ZigZag Conversion字符串Z形排列
The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like ...
- Android Studio 减小项目文件夹的大小和.gitignore文件配置
Build --> Clean Project 可以清理出很大一部分的空间 手动删除以下文件或者目录 Dir : ProjectFolder/buildDir : ProjectFolder/a ...
- Tomcat的三种部署方式
Tomcat是目前web开发中非常流行的Web 服务器,也就是tomcat在部署项目的时候,必须要把应用程序中所用到的jar包放到tomcat的lib目录下,然后再一起部署到服务器上. 那么tomca ...