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

Spring5源码解析1-从启动容器开始

程序员文章站 2022-04-17 21:53:49
Spring5源码解析Annotation版本。从最简单的启动容器开始解析源码:new AnnotationConfigApplicationContext(AppConfig.class); ......

从启动容器开始

最简单的启动spring的代码如下:

@configuration
@componentscan
public class appconfig {
}

public class main {
    public static void main(string[] args) {
        annotationconfigapplicationcontext context =
                new annotationconfigapplicationcontext(appconfig.class);
        context.close();
    }
}

先来看一下annotationconfigapplicationcontext类的uml图,留个印象。

Spring5源码解析1-从启动容器开始

点开annotationconfigapplicationcontext(appconfig.class);方法查看源码:

public annotationconfigapplicationcontext(class<?>... annotatedclasses) {
    //调用默认无参构造器,里面有一大堆初始化逻辑
    this();

    //把传入的class进行注册,class既可以有@configuration注解,也可以没有@configuration注解
    //怎么注册? 委托给了 org.springframework.context.annotation.annotatedbeandefinitionreader.register 方法进行注册
    // 传入class 生成  beandefinition , 然后通过 注册到 beandefinitionregistry
    register(annotatedclasses);

    //刷新容器上下文
    refresh();
}

该构造器允许我们传入一个或者多个class对象。class对象可以是被@configuration标注的,也可以是一个普通的java 类。

有参构造器调用了无参构造器,点开源码:

public annotationconfigapplicationcontext() {
    //隐式调用父类构造器,初始化beanfactory,具体实现类为defaultlistablebeanfactory
    super(); // 这个代码是笔者添加的,方便定位到super方法

    //创建 annotatedbeandefinitionreader,
    //创建时会向传入的 beandefinitionregistry 中 注册 注解配置相关的 processors 的 beandefinition
    this.reader = new annotatedbeandefinitionreader(this);

    this.scanner = new classpathbeandefinitionscanner(this);
}

初始化子类时会先初始化父类,会默认调用父类无参构造器。annotationconfigapplicationcontext继承了genericapplicationcontext,在genericapplicationcontext的无参构造器中,创建了beanfactory的具体实现类defaultlistablebeanfactory。spring中的beanfactory就是在这里被实例化的,并且使用defaultlistablebeanfactory做的beanfactory的默认实现。

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

Spring5源码解析1-从启动容器开始

annotationconfigapplicationcontext的构造器中还创建了两个对象:annotatedbeandefinitionreaderclasspathbeandefinitionscanner

先说scanner的作用,通过查看源码可以发现,这个scanner只有在手动调用annotationconfigapplicationcontext的一些方法的时候才会被使用(通过后面的源码探究也可以发现,spring并不是使用这个scanner来扫描包获取bean的)。

Spring5源码解析1-从启动容器开始

创建annotatedbeandefinitionreader对象。spring在创建reader的时候把this当做了参数传给了构造器。也就是说,reader对象里面包含了一个this对象,也就是annotationconfigapplicationcontext对象。annotationconfigapplicationcontext 实现了beandefinitionregistry接口。点开this.reader = new annotatedbeandefinitionreader(this);源码:

public annotatedbeandefinitionreader(beandefinitionregistry registry) {
    this(registry, getorcreateenvironment(registry));
}

从传入的beandefinitionregistry对象,也就是annotationconfigapplicationcontext对象中获取environment(共用同一个environment),然后又接着调用另一个构造器。点开源码:

public annotatedbeandefinitionreader(beandefinitionregistry registry, environment environment) {
    assert.notnull(registry, "beandefinitionregistry must not be null");
    assert.notnull(environment, "environment must not be null");
    this.registry = registry;
    this.conditionevaluator = new conditionevaluator(registry, environment, null);
    //在 beandefinitionregistry 中注册 注解配置相关的 processors
    annotationconfigutils.registerannotationconfigprocessors(this.registry);
}

在这个构造器中,执行了一个非常重要的方法annotationconfigutils.registerannotationconfigprocessors(this.registry);,顾名思义,spring通过这个方法注册了解析注解配置相关的处理器。点开源码:

public static void registerannotationconfigprocessors(beandefinitionregistry registry) {
    registerannotationconfigprocessors(registry, null);
}
//再点开源码
public static set<beandefinitionholder> registerannotationconfigprocessors(
        beandefinitionregistry registry, @nullable object source) {

    defaultlistablebeanfactory beanfactory = unwrapdefaultlistablebeanfactory(registry);
    if (beanfactory != null) {
        if (!(beanfactory.getdependencycomparator() instanceof annotationawareordercomparator)) {
            beanfactory.setdependencycomparator(annotationawareordercomparator.instance);
        }
        if (!(beanfactory.getautowirecandidateresolver() instanceof contextannotationautowirecandidateresolver)) {
            beanfactory.setautowirecandidateresolver(new contextannotationautowirecandidateresolver());
        }
    }

    set<beandefinitionholder> beandefs = new linkedhashset<>(8);

    if (!registry.containsbeandefinition(configuration_annotation_processor_bean_name)) {
        //org.springframework.context.annotation.internalconfigurationannotationprocessor - configurationclasspostprocessor.class
        //这个类非常的重要,它是一个 beandefinitionregistrypostprocessor
        rootbeandefinition def = new rootbeandefinition(configurationclasspostprocessor.class);
        def.setsource(source);
        beandefs.add(registerpostprocessor(registry, def, configuration_annotation_processor_bean_name));
    }

    if (!registry.containsbeandefinition(autowired_annotation_processor_bean_name)) {
        rootbeandefinition def = new rootbeandefinition(autowiredannotationbeanpostprocessor.class);
        def.setsource(source);
        beandefs.add(registerpostprocessor(registry, def, autowired_annotation_processor_bean_name));
    }

    // check for jsr-250 support, and if present add the commonannotationbeanpostprocessor.
    if (jsr250present && !registry.containsbeandefinition(common_annotation_processor_bean_name)) {
        rootbeandefinition def = new rootbeandefinition(commonannotationbeanpostprocessor.class);
        def.setsource(source);
        beandefs.add(registerpostprocessor(registry, def, common_annotation_processor_bean_name));
    }

    // check for jpa support, and if present add the persistenceannotationbeanpostprocessor.
    if (jpapresent && !registry.containsbeandefinition(persistence_annotation_processor_bean_name)) {
        rootbeandefinition def = new rootbeandefinition();
        try {
            def.setbeanclass(classutils.forname(persistence_annotation_processor_class_name,
                    annotationconfigutils.class.getclassloader()));
        } catch (classnotfoundexception ex) {
            throw new illegalstateexception(
                    "cannot load optional framework class: " + persistence_annotation_processor_class_name, ex);
        }
        def.setsource(source);
        beandefs.add(registerpostprocessor(registry, def, persistence_annotation_processor_bean_name));
    }

    if (!registry.containsbeandefinition(event_listener_processor_bean_name)) {
        rootbeandefinition def = new rootbeandefinition(eventlistenermethodprocessor.class);
        def.setsource(source);
        beandefs.add(registerpostprocessor(registry, def, event_listener_processor_bean_name));
    }

    if (!registry.containsbeandefinition(event_listener_factory_bean_name)) {
        rootbeandefinition def = new rootbeandefinition(defaulteventlistenerfactory.class);
        def.setsource(source);
        beandefs.add(registerpostprocessor(registry, def, event_listener_factory_bean_name));
    }

    return beandefs;
}
  1. 该方法从传入的beandefinitionregistry对象,也就是annotationconfigapplicationcontext对象中获取到defaultlistablebeanfactory对象。
  2. 为获取的defaultlistablebeanfactory对象设置属性
  3. defaultlistablebeanfactory对象中注册beandefinition,注册的是一些spring内置的postprocessor的beandefinition(关于beandefinition的介绍下期在讲)。注意,此时只是注册beandefinition,并没有实例化bean。默认情况下,执行完该方法后,spring容器中所注册的beandefinition为:

Spring5源码解析1-从启动容器开始


源码学习笔记:https://github.com/shenjianeng/spring-code-study