前言:在【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方法中可以看到如下代码:

  1. // AbstractAutowireCapableBeanFactory
  2. private void invokeAwareMethods(final String beanName, final Object bean) {
  3. if (bean instanceof Aware) {
  4. // BeanNameAware
  5. if (bean instanceof BeanNameAware) {
  6. ((BeanNameAware) bean).setBeanName(beanName);
  7. }
  8. // BeanClassLoaderAware
  9. if (bean instanceof BeanClassLoaderAware) {
  10. ClassLoader bcl = getBeanClassLoader();
  11. if (bcl != null) {
  12. ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
  13. }
  14. }
  15. // BeanFactoryAware
  16. if (bean instanceof BeanFactoryAware) {
  17. ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
  18. }
  19. }
  20. }

分析:

首先判断bean是否实现了Aware接口,如果是则调用实例的setXXX()方法给实例设置xxx属性,在invokeAwareMethods方法中,主要处理BeanNameAware、BeanClassLoaderAware、BeanFactoryAware三种接口,也从侧面证实了Spring只会处理实现了这三种接口中任意一个的bean实例。

Aware示例演示

下面就演示Spring是如何处理实现这三个接口的bean的:

  1. public class UserDefinedAware implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware {
  2.  
  3. private String name;
  4. private ClassLoader classLoader;
  5. private BeanFactory beanFactory;
  6.  
  7. @Override
  8. public void setBeanName(String name) {
  9. System.out.println("调用了 BeanNameAware 的 setBeanName方法");
  10. this.name = name;
  11. }
  12.  
  13. @Override
  14. public void setBeanClassLoader(ClassLoader classLoader) {
  15. System.out.println("调用了 BeanClassLoader 的 setBeanClassLoader 方法");
  16. this.classLoader = classLoader;
  17. }
  18.  
  19. @Override
  20. public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
  21. System.out.println("调用了 BeanFactoryAware 的 setBeanFactory 方法");
  22. this.beanFactory = beanFactory;
  23. }
  24.  
  25. public void showMsg() {
  26. System.out.println("beanName=" + this.name);
  27. System.out.println("classLoader=" + this.classLoader.getClass());
  28. System.out.println("是否为单例=" + beanFactory.isSingleton(this.name));
  29. }
  30. }

测试方法如下:

  1. /**
  2. * Aware接口演示
  3. */
  4. @Test
  5. public void awareTest() {
  6. ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:com/dev/config/aware/aware.xml");
  7. UserDefinedAware userDefinedAware = context.getBean(UserDefinedAware.class);
  8. userDefinedAware.showMsg();
  9. }

输出结果如下:

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容器初始化——查漏补缺(一)的更多相关文章

  1. 【spring源码分析】IOC容器初始化——查漏补缺(五)

    前言:我们知道在Spring中经常使用配置文件的形式对进行属性的赋值,那配置文件的值是怎么赋值到属性上的呢,本文将对其进行分析. 首先了解一个类:PropertySourcesPlaceholderC ...

  2. 【spring源码分析】IOC容器初始化——查漏补缺(二)

    前言:在[spring源码分析]IOC容器初始化(八)中多次提到了前置处理与后置处理,本篇文章针对此问题进行分析.Spring对前置处理或后置处理主要通过BeanPostProcessor进行实现. ...

  3. 【spring源码分析】IOC容器初始化——查漏补缺(四)

    前言:在前几篇查漏补缺中,其实我们已经涉及到bean生命周期了,本篇内容进行详细分析. 首先看bean实例化过程: 分析: bean实例化开始后 注入对象属性后(前面IOC初始化十几篇文章). 检查激 ...

  4. SPRING源码分析:IOC容器

    在Spring中,最基本的IOC容器接口是BeanFactory - 这个接口为具体的IOC容器的实现作了最基本的功能规定 - 不管怎么着,作为IOC容器,这些接口你必须要满足应用程序的最基本要求: ...

  5. 【spring源码分析】IOC容器初始化——查漏补缺(三)

    前言:本文分析InitializingBean和init-method方法,其实该知识点在AbstractAutowireCapableBeanFactory#initializeBean方法中有所提 ...

  6. Spring源码解析-ioc容器的设计

    Spring源码解析-ioc容器的设计 1 IoC容器系列的设计:BeanFactory和ApplicatioContext 在Spring容器中,主要分为两个主要的容器系列,一个是实现BeanFac ...

  7. spring源码分析---IOC(1)

    我们都知道spring有2个最重要的概念,IOC(控制反转)和AOP(依赖注入).今天我就分享一下spring源码的IOC. IOC的定义:直观的来说,就是由spring来负责控制对象的生命周期和对象 ...

  8. spring 源码之 ioc 容器的初始化和注入简图

    IoC最核心就是两个过程:IoC容器初始化和IoC依赖注入,下面通过简单的图示来表述其中的关键过程:

  9. Spring源码阅读-IoC容器解析

    目录 Spring IoC容器 ApplicationContext设计解析 BeanFactory ListableBeanFactory HierarchicalBeanFactory Messa ...

随机推荐

  1. c# post 接收传来的文件

    private void UploadFile() { // //......其他代码 // HttpFileCollection files = HttpContext.Current.Reques ...

  2. leetcode102

    本题是广度优先遍历(BFS)实现树的层次遍历,使用队列实现. class Solution { public: vector<vector<int>> levelOrder(T ...

  3. jqueryValidate

    参数详情可参见: http://www.runoob.com/jquery/jquery-plugin-validate.html 基本使用: /** 数据保存前校验 **/ $("#use ...

  4. 2018 pycharm最近激活码

    今天更新了一下pycharm,结果之前的激活就不能用了,下面是新的激活方法: 1.mac下在终端进入etc目录: cd /etc 2.编辑hosts文件: vi hosts 将“0.0.0.0 acc ...

  5. playbook

    1 --- - hosts: web-server 3 remote_user: root tasks: - name: stop logstash shell: PID=` $PID &&a ...

  6. (转)PWA(Progressive Web App)渐进式Web应用程序

    PWA 编辑 讨论 PWA(Progressive Web App)是一种理念,使用多种技术来增强web app的功能,可以让网站的体验变得更好,能够模拟一些原生功能,比如通知推送.在移动端利用标准化 ...

  7. MFC笔记6

    1.MFC文件的读写操作 写操作 创建一个编辑框(IDC_INFOR_EDIT1),在里面输入信息,创建一个按钮(IDC_BUTTON),点击按钮会触发(OnBnClickedButton2()函数) ...

  8. Codeforces Round #436 A. Fair Game

    题意:给你n张卡片,上面写有数字,两个人选择两个数字,把相同数字的卡片都拿走,问能不能拿走所有的卡片并且两个人拿的卡片书相同. Examples Input 411272711 Output YES1 ...

  9. NodeJs第3方包说明

    formidable 作用:实现简单文件上传 var formidable = require('formidable'); var form = new formidable.IncomingFor ...

  10. springcloud ConfigServer的工作原理

    前话 根据前文得知,bootstrapContext引入了PropertySourceLocator接口供外部源加载配置,但作用是应用于子级ApplicationContext的环境变量Environ ...