Spring是如何回调Aware系列接口?

作者: 大道至简_Andy | 来源:发表于2017-01-09 17:34 被阅读1034次

写在最前

当我们运行Web容器或是以SE的方式运行Spring程序的过程中,你有没有想过Spring是如何实现回调生命周期中的那些过程呢?今天我们就以生命周期中回调Aware接口为例,来说说Spring的回调过程。

正文

1.Aware接口

Aware接口

Aware接口在Spring的3.1版本中出现,并且beans包中,属于spring的核心。上图中的描述告诉我们,Aware是一个具有标识作用的超级接口,实现该接口的bean是具有被spring 容器通知的能力的,而被通知的方式就是通过回调。对于这段英文,我并没有直译,而是加上了自己的理解。总之,一句话也就是说:直接或间接实现了这个接口的类,都具有被spring容器通知的能力。

那我们看看spring中实现了该超级接口的子接口有哪些?

Aware的子接口

哇,多如牛毛!咦,别动,有几个好熟悉的接口。例如:ResourceLoaderAware、BeanNameAware、ApplicationContextAware、BeanNameAware... 熟悉spring生命周期的童鞋可能见过这些接口。不错,这些接口就是今天我们的主角。

2.Spring Boot的大致启动过程

我们以Spring Boot的启动过程为例,看看这些Aware接口是如何被调用到的。

Spring Boot启动入口

如上图,这里是以内嵌jetty的方式启动Spring Boot。 通常我们启动Spring boot,都是直接调用SpringApplication的run方法,再看看run方法的内部:

SpringApplication的run方法

主要看红色圈起的地方,其它的代码可以忽略。这里调用了createApplicationContext方法去创建容器上下文。再来看看createApplicationContext()方法的内部:

SpringApplication的createApplicationContext方法 SpringApplication的常量

webEnvironment是一个boolean型的变量,用来表示当前的应用类型是不是web应用。如果为false,则代表是普通应用(JavaSE);反之就是web应用(Java Web),则创建可运行web应用的上下文。我们讲述的是web应用,所以这里的contextClass是AnnotationConfigEmbeddedWebApplicationContext。createApplicationContext()方法中的最后一行代码是创建了一个context。我们跟进去看看这个context是如何创建的:

BeanUtils的instantiate()方法

上图中的第七行代码,通过反射实例化了contextClass,这里实例化的正是AnnotationConfigEmbeddedWebApplicationContext类,调用的是无参的构造器。我们再去看看AnnotationConfigEmbeddedWebApplicationContext的无参构造器:

AnnotationConfigEmbeddedWebApplicationContext的无参构造器

如上图,构造器中只是设置了reader和scanner。这里我们先忽略它们。除此之外,实例化一个类时它的直接或间接的父类也同样会被实例化。看看AnnotationConfigEmbeddedWebApplicationContext有些哪些父类:

AnnotationConfigEmbeddedWebApplicationContext的继承关系

我们耐心的一层一层的跟踪父类和间接父类的构造器到GenericApplicationContext才发现无参构造器中在做一些事情。如下图:

GenericApplicationContext

看到这里,我们终于看见曙光了。xxxBeanFactory是生成beans对象的工厂类。在DefaultListableBeanFactory的父类AbstractAutowireCapableBeanFactory中有两个很重要的方法:
initializeBean()和createBean()方法。initializeBean是用来初始化beans的,看下图代码:

AbstractAutowireCapableBeanFactory的initializeBean方法

看到这里我们就知道了,Aware系列的接口是这么被调用的了,并把需要的内部对象回传给Aware的子类实例对象,那么外部就可以获取到spring内部的一些对象了。例如:我们获取BeanFactory,然后手动创建beans对象等等。

写在最后

看完上面的过程有没有发现少了点什么东西? 是不是发现少了:Spring Boot是如何调用到initializeBean()的呢?欲知后事如何,且看下回分解。

相关文章

  • Spring是如何回调Aware系列接口?

    写在最前 当我们运行Web容器或是以SE的方式运行Spring程序的过程中,你有没有想过Spring是如何实现回调...

  • Spring Boot是如何调用到initializeBean(

    写在最前 《Spring是如何回调Aware系列接口?》这篇文章的最后留了个小尾巴,下面我们就围绕着这个“小尾巴”...

  • SpringIoc之Aware

    Aware 概述 Aware是Spring提供的一个标记超接口,指示bean有资格通过回调样式的方法由Spring...

  • 初始化过程

    1. 先回调Aware接口 2. 回调BeanPostProcessor#postProcessBeforeIni...

  • Spring系列之-Aware系列接口

    Spring系列之-Aware系列接口 功能介绍: 1.ApplicationContextAware 实现App...

  • Spring Aware容器感知技术

    ​ Spring Aware是什么 Spring提供Aware接口能让Bean感知Spring容器的存在,即让Be...

  • spring的aware们

    Aware是什么 spring框架提供了多个*Aware接口,用于辅助Spring Bean编程访问Spring容...

  • Aware Mode

    Aware接口 Spring中提供了一些以Aware结尾的接口,实现了Aware接口的bean在被初始化之后,可以...

  • Spring知识点整理(持续更新)

    Aware接口使用 Spring中Aware.java是个没有任何方法的接口,有很多子接口,常见的比如BeanNa...

  • Spring5IOC容器解析——Aware接口

    Aware Aware 是 Spring 中的一个根接口,继承该接口的子接口有很多,但是该接口没有任何方法,所以大...

网友评论

    本文标题:Spring是如何回调Aware系列接口?

    本文链接:https://www.haomeiwen.com/subject/wtkhbttx.html