欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

初探Spring源码之Spring Bean的生命周期

程序员文章站 2024-02-05 21:10:10
写在前面的话: 学无止境,写博客纯粹是一种乐趣而已,把自己理解的东西分享出去,不意味全是对的,欢迎指正! Spring 容器初始化过程做了什么? Spring 容器初始化过程做了什么? 实例了一个 AnnotationConfigApplicationContext对象,Spring中出来注解Bea ......

写在前面的话:

  学无止境,写博客纯粹是一种乐趣而已,把自己理解的东西分享出去,不意味全是对的,欢迎指正!

 

  • spring 容器初始化过程做了什么?

1 annotationconfigapplicationcontext applicationcontext = new annotationconfigapplicationcontext();
  • 实例了一个 annotationconfigapplicationcontext对象,spring中出来注解bean定义的类有两个:

annotationconfigapplicationcontext和annotationconfigwebapplicationcontex annotationconfigwebapplicationcontextannotationconfigapplicationcontext的web版本,两者的用法以及对注解的处理方式几乎没有什么差别,通过分析这个类我们知道注册一个bean到spring容器有两种办法一、直接将注解bean注册到容器中:(参考)public void register(class<?>... annotatedclasses)但是直接把一个注解的bean注册到容器当中也分为两种方法:

  1、在初始化容器时注册并且解析

  2、也可以在容器创建之后手动调用注册方法向容器注册,然后通过手动刷新容器,使得容器对注册的注解bean进行处理。

思考:为什么@profile要使用这类的第2种方法?

因为需要通过applicationcontext.getenvironment()这样的方式设置环境或者获取环境变量

二、通过扫描指定的包及其子包下的所有类扫描其实同上,也是两种方法,初始化的时候扫描,和初始化之后再扫描

 1 public annotationconfigapplicationcontext() {//0
 2    /**
 3     * 父类的构造方法
 4     * 创建一个读取注解的bean定义读取器
 5     * 什么是bean定义?beandefinition
 6     */
 7    this.reader = new annotatedbeandefinitionreader(this); //1
 8 ​
 9    //可以用来扫描包或者类,继而转换成bd
10    //但是实际上我们扫描包工作不是scanner这个对象来完成的
11    //是spring自己new的一个classpathbeandefinitionscanner
12    //这里的scanner仅仅是为了程序员能够在外部调用annotationconfigapplicationcontext对象的scan方法
13    this.scanner = new classpathbeandefinitionscanner(this); //2
14 }

 

注意: * 初始化一个bean的读取和扫描器 * 何谓读取器和扫描器参考上面的属性注释

      * 默认构造函数,如果直接调用这个默认构造方法,需要在稍后通过调用其register()

    * 去注册配置类(javaconfig),并调用refresh()方法刷新容器,

    * 触发容器对注解bean的载入、解析和注册过程

 

  • 实例化annotationconfigapplicationcontext会先实例化父类genericapplicationcontext,然后初始化一个bean工厂,defaultlistablebeanfactory

    1 public genericapplicationcontext() {
    2    this.beanfactory = new defaultlistablebeanfactory();
    3 }

     

  • 1处,实例化一个beandefinition读取器 annotatedbeandefinitionreader

 1 /**
 2  *  这里的beandefinitionregistry registry是通过在annotationconfigapplicationcontext
 3  *  的构造方法中传进来的this
 4  *  由此说明annotationconfigapplicationcontext是一个beandefinitionregistry类型的类
 5  *  何以证明我们可以看到annotationconfigapplicationcontext的类关系:
 6  *  genericapplicationcontext extends abstractapplicationcontext implements beandefinitionregistry
 7  *  看到他实现了beandefinitionregistry证明上面的说法,那么beandefinitionregistry的作用是什么呢?
 8  *  beandefinitionregistry 顾名思义就是beandefinition的注册器
 9  *  那么何为beandefinition呢?参考beandefinition的源码的注释
10  * @param registry
11  */
12 public annotatedbeandefinitionreader(beandefinitionregistry registry) {
13    this(registry, getorcreateenvironment(registry));
14 }
15     public annotatedbeandefinitionreader(beandefinitionregistry registry, environment environment) {
16       assert.notnull(registry, "beandefinitionregistry must not be null");
17       assert.notnull(environment, "environment must not be null");
18       this.registry = registry;
19       this.conditionevaluator = new conditionevaluator(registry, environment, null);
20       annotationconfigutils.registerannotationconfigprocessors(this.registry);
21    }

 

annotationconfigutils.registerannotationconfigprocessors(this.registry);

1 public static void registerannotationconfigprocessors(beandefinitionregistry registry) {
2    registerannotationconfigprocessors(registry, null);

 

以上空壳方法,调用以下方法

1 1 public static set<beandefinitionholder> registerannotationconfigprocessors(
2 2       beandefinitionregistry registry, @nullable object source) {
3 3 //主要是为了获得工厂对象,实例化annotationconfigapplicationcontext的时候会调用父类
4 4 //genericapplicationcontext的构造器去实例化defaultlistablebeanfactory
5 5 //这里的registry其实际是genericapplicationcontext的子类实例,向上转型取得工厂的属性
6 6 //从而得到 beanfactory对象
7 7 defaultlistablebeanfactory beanfactory = unwrapdefaultlistablebeanfactory(registry);

 

获得工厂的具体逻辑

private static defaultlistablebeanfactory unwrapdefaultlistablebeanfactory(beandefinitionregistry registry) {
   if (registry instanceof defaultlistablebeanfactory) {
      return (defaultlistablebeanfactory) registry;
   }
   else if (registry instanceof genericapplicationcontext) {
      //这里在annotationconfigapplicationcontext初始化的时候this()
      //方法中调用了父类genericapplicationcontext的时候new了一个defaultlistablebeanfactory对象
      //下面代码返回这个对象
      return ((genericapplicationcontext) registry).getdefaultlistablebeanfactory();
   }
   else {
      return null;
   }
}

 

这段代码主要是为解析是否含有需要排序的注解

 1 if (beanfactory != null) {
 2    if (!(beanfactory.getdependencycomparator() instanceof annotationawareordercomparator)) {
 3       //annotationawareordercomparator主要能解析@order注解和@priority
 4       beanfactory.setdependencycomparator(annotationawareordercomparator.instance);
 5    }
 6    if (!(beanfactory.getautowirecandidateresolver() instanceof contextannotationautowirecandidateresolver)) {
 7       //contextannotationautowirecandidateresolver提供处理延迟加载的功能
 8       beanfactory.setautowirecandidateresolver(new contextannotationautowirecandidateresolver());
 9    }
10 }

 

org.springframework.context.annotation.internalconfigurationannotationprocessor这个是beandefinition

的一个beanname, 具体的类是configurationclasspostprocessor,它在beandefinition中表现的是一个后置处理器(重要),是spring的核心类之一。

 1 set<beandefinitionholder> beandefs = new linkedhashset<>(8);
 2 //beandefinitio的注册,这里很重要,需要理解注册每个bean的类型
 3 //org.springframework.context.annotation.internalconfigurationannotationprocessor
 4 //这个是spring生命周期非常重要的一个类
 5 if (!registry.containsbeandefinition(configuration_annotation_processor_bean_name)) {
 6    //需要注意的是configurationclasspostprocessor的类型是beandefinitionregistrypostprocessor
 7    //而 beandefinitionregistrypostprocessor 最终实现beanfactorypostprocessor这个接口
 8    //因此需要对这两种类型的进行区分处理
 9 ​
10    //将一个类变成beandefinition
11    rootbeandefinition def = new rootbeandefinition(configurationclasspostprocessor.class);
12    def.setsource(source);
13    //这里是将bd注册到beanfactory的beandefinitionmap容器中,并返回一个
14    //beandefinitionholder对象
15    beandefs.add(registerpostprocessor(registry, def, configuration_annotation_processor_bean_name));
16 }

 

实际上上面的代码和以下的代码主要往defaultlistablebeanfactory中的beandefinitionmap 中放入以下所列举的6个后置处理器。其中configurationclasspostprocessor是核心

0.org.springframework.context.annotation.configurationclasspostprocessor(重要)

1.org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor

2.org.springframework.beans.factory.annotation.requiredannotationbeanpostprocessor

3.org.springframework.context.annotation.commonannotationbeanpostprocessor

4.org.springframework.context.event.eventlistenermethodprocessor

5.org.springframework.context.event.defaulteventlistenerfactory

 1 if (!registry.containsbeandefinition(autowired_annotation_processor_bean_name)) {
 2    //autowiredannotationbeanpostprocessor 实现了 mergedbeandefinitionpostprocessor
 3    //mergedbeandefinitionpostprocessor 最终实现了 beanpostprocessor
 4    rootbeandefinition def = new rootbeandefinition(autowiredannotationbeanpostprocessor.class);
 5    def.setsource(source);
 6    beandefs.add(registerpostprocessor(registry, def, autowired_annotation_processor_bean_name));
 7 }
 8 ​
 9 if (!registry.containsbeandefinition(required_annotation_processor_bean_name)) {
10    rootbeandefinition def = new rootbeandefinition(requiredannotationbeanpostprocessor.class);
11    def.setsource(source);
12    beandefs.add(registerpostprocessor(registry, def, required_annotation_processor_bean_name));
13 }
14 ​
15 // check for jsr-250 support, and if present add the commonannotationbeanpostprocessor.
16 if (jsr250present && !registry.containsbeandefinition(common_annotation_processor_bean_name)) {
17    rootbeandefinition def = new rootbeandefinition(commonannotationbeanpostprocessor.class);
18    def.setsource(source);
19    beandefs.add(registerpostprocessor(registry, def, common_annotation_processor_bean_name));
20 }
21 ​
22 // check for jpa support, and if present add the persistenceannotationbeanpostprocessor.
23 if (jpapresent && !registry.containsbeandefinition(persistence_annotation_processor_bean_name)) {
24    rootbeandefinition def = new rootbeandefinition();
25    try {
26       def.setbeanclass(classutils.forname(persistence_annotation_processor_class_name,
27             annotationconfigutils.class.getclassloader()));
28    }
29    catch (classnotfoundexception ex) {
30       throw new illegalstateexception(
31             "cannot load optional framework class: " + persistence_annotation_processor_class_name, ex);
32    }
33    def.setsource(source);
34    beandefs.add(registerpostprocessor(registry, def, persistence_annotation_processor_bean_name));
35 }
36 ​
37 if (!registry.containsbeandefinition(event_listener_processor_bean_name)) {
38    rootbeandefinition def = new rootbeandefinition(eventlistenermethodprocessor.class);
39    def.setsource(source);
40    beandefs.add(registerpostprocessor(registry, def, event_listener_processor_bean_name));
41 }
42 ​
43 if (!registry.containsbeandefinition(event_listener_factory_bean_name)) {
44    rootbeandefinition def = new rootbeandefinition(defaulteventlistenerfactory.class);
45    def.setsource(source);
46    beandefs.add(registerpostprocessor(registry, def, event_listener_factory_bean_name));
47 }

 

疑问1:普通的对象是怎么变成beandefinition的呢?

//将一个类变成beandefinition
rootbeandefinition def = new rootbeandefinition(configurationclasspostprocessor.class);

 

疑问2:对象变成beandefinition之后又是怎么注册到bean工厂的呢?

1 private static beandefinitionholder registerpostprocessor(
2       beandefinitionregistry registry, rootbeandefinition definition, string beanname) {
3 ​
4    definition.setrole(beandefinition.role_infrastructure);
5    //将bd注册到工厂的beandefinitionmap中
6    registry.registerbeandefinition(beanname, definition);
7    //beandefinitionholder 只是封装参数使用
8    return new beandefinitionholder(definition, beanname);
9 }

 

registry.registerbeandefinition(beanname, definition);这句代码将beandefinition注册到beanfactory中

注意这里的registry注册器一直都是annotationconfigapplicationcontext对象,该类中没有registerbeandefinition() ,因此会调用父类genericapplicationcontext的registerbeandefinition()方法注册beandefinition。

1 public void registerbeandefinition(string beanname, beandefinition beandefinition)
2       throws beandefinitionstoreexception {
3 ​
4    this.beanfactory.registerbeandefinition(beanname, beandefinition);
5 }

 

调用org.springframework.beans.factory.support.defaultlistablebeanfactory#registerbeandefinition()的方法执行以下逻辑

1 public void registerbeandefinition(string beanname, beandefinition beandefinition)
2       throws beandefinitionstoreexception {

 

不管genericbeandefinition,还是rootbeandefinition都继承了abstractbeandefinition,因此会执行以下逻辑

 1 assert.notnull(beandefinition, "beandefinition must not be null");
 2 //beandefinition的所有实现类都继承了abstractbeandefinition,因此会执行以下的检验逻辑
 3 if (beandefinition instanceof abstractbeandefinition) {
 4    try {
 5       ((abstractbeandefinition) beandefinition).validate();
 6    }
 7    catch (beandefinitionvalidationexception ex) {
 8       throw new beandefinitionstoreexception(beandefinition.getresourcedescription(), beanname,
 9             "validation of bean definition failed", ex);
10    }
11 }

 

执行一些逻辑判断,打印一些log,这些不重要

 1 //根据beanname从容器中取出bd,判断是否已经注册了的各种校验
 2 beandefinition existingdefinition = this.beandefinitionmap.get(beanname);
 3 if (existingdefinition != null) {
 4     //是否允许覆盖原有的bean 默认是不覆盖
 5    if (!isallowbeandefinitionoverriding()) {
 6       throw new beandefinitionstoreexception(beandefinition.getresourcedescription(), beanname,
 7             "cannot register bean definition [" + beandefinition + "] for bean '" + beanname +
 8             "': there is already [" + existingdefinition + "] bound.");
 9    }
10    else if (existingdefinition.getrole() < beandefinition.getrole()) {
11       // e.g. was role_application, now overriding with role_support or role_infrastructure
12       if (logger.iswarnenabled()) {
13          logger.warn("overriding user-defined bean definition for bean '" + beanname +
14                "' with a framework-generated bean definition: replacing [" +
15                existingdefinition + "] with [" + beandefinition + "]");
16       }
17    }
18    else if (!beandefinition.equals(existingdefinition)) {
19       if (logger.isinfoenabled()) {
20          logger.info("overriding bean definition for bean '" + beanname +
21                "' with a different definition: replacing [" + existingdefinition +
22                "] with [" + beandefinition + "]");
23       }
24    }
25    else {
26       if (logger.isdebugenabled()) {
27          logger.debug("overriding bean definition for bean '" + beanname +
28                "' with an equivalent definition: replacing [" + existingdefinition +
29                "] with [" + beandefinition + "]");
30       }
31    }
32     //加入到beandefinitionmap当中,正常第一次不会走到这里
33    this.beandefinitionmap.put(beanname, beandefinition);
34 }
35 else {
36    if (hasbeancreationstarted()) {
37       // cannot modify startup-time collection elements anymore (for stable iteration)
38       synchronized (this.beandefinitionmap) {
39           //这里加锁的意义是防止正在创建的bean被修改。
40          this.beandefinitionmap.put(beanname, beandefinition);
41          list<string> updateddefinitions = new arraylist<>(this.beandefinitionnames.size() + 1);
42          updateddefinitions.addall(this.beandefinitionnames);
43          updateddefinitions.add(beanname);
44          this.beandefinitionnames = updateddefinitions;
45          if (this.manualsingletonnames.contains(beanname)) {
46             set<string> updatedsingletons = new linkedhashset<>(this.manualsingletonnames);
47             updatedsingletons.remove(beanname);
48             this.manualsingletonnames = updatedsingletons;
49          }
50       }
51    }

 

初次注册beandefinition的会执行

1 else {
2    // still in startup registration phase
3     //初次注册会执行这段逻辑,90%的注册会走到这里
4    this.beandefinitionmap.put(beanname, beandefinition);
5    this.beandefinitionnames.add(beanname);
6    this.manualsingletonnames.remove(beanname);
7 }
8 this.frozenbeandefinitionnames = null;

 

 

至此,实例化一个annotationbeandefinitionreader会注册6个后置处理器,为什么注册这些后置处理器,有什么作用,会在后续的spring源码解析中进行讲解。另外核心的类configurationclasspostprocessor的作用是什么?

 

  • 2处,实例化一个beandefinition 扫描器classpathbeandefinitionscanner

    beandefinition扫描器这里不做多介绍,因为这里的扫描器主要是为了给程序员自己定义一个类的扫描器,用来扫描我们自定义的加了注解类。

    疑问3:spring是怎么扫描被注解标识的类呢?

  • 如加了@component @controller @service @repository 等等,其实用的也是classpathbeandefinitionscanner,只不过spring内部它自己实例化了一个,并不是用的这里这个而已,后续会进行解析和讲解。