当前位置:   article > 正文

Spring Boot技术内 幕:架构设计与实现原理

Spring Boot技术内 幕:架构设计与实现原理

第一部分 准备篇

第1章 阅读代码前的准备

1.1 获取和调试Spring Boot源代码

1.1.1 获取Spring Boot的源代码获取

Spring Boot源代码有两种方式:直接获取整个项目源代码,创建Maven项目后间接加载源代码。我推荐使用第二种方式。

1.1.2 调试Spring Boot的源代码

Spring Boot默认采用main方法启动,入口方法为SpringApplication类的run方法。

1.2 Spring Boot源代码的目录结构

1.3 源代码阅读工具

        常见的代码阅读工具,比如Intellij IDEA、Spring Tool Suite、Eclipse、MyEclipse等。

1.4 Spring Boot的设计理念和目标

        Spring Boot本身并不提供Spring的核心功能,而是作为Spring的脚手架框架,以达到快速构建项目、预置三方配置、开箱即用的目的。

1.4.1 设计理念

        约定优于配置(Convention Over Configuration),又称为按约定编程,是一种软件设计范式,旨在减少软件开发人员需要做决定的数量,执行起来简单而又不失灵活。

        Starter作为SpringBoot的核心功能之一,基于自动配置代码提供了自动配置模块及依赖,让软件集成变得简单、易用。

1.5 Spring Boot的整体架构

        图1-4中为了更清晰地表达Spring Boot各项目之间的关系,我们基于依赖的传递性,省略了部分依赖关系。比如,Spring Boot Starters不仅依赖了Spring Boot Autoconfigure项目,还依赖了SpringBoot和Spring,而Spring Boot Autoconfigure项目又依赖了Spring Boot,Spring Boot又依赖了Spring相关项目。因此在图中就省略了Spring Boot Starters和底层依赖的关联。

        从图1-4中可以看到Spring Boot几乎完全基于Spring,同时提供了Spring Boot和SpringBoot Autoconfigure两个核心的模块,而其他相关功能又都是基于这两个核心模块展开的。

第二部分 原理篇

第2章 Spring Boot核心运行原理

        Spring Boot最核心的功能就是自动配置,功能的实现都是基于“约定优于配置”的原则。Spring Boot是如何约定,又是如何实现自动配置功能的呢?

2.1 核心运行原理

        使用Spring Boot时只需引入对应的Starters,Spring Boot启动时便会自动加载相关依赖,配置相应的初始化参数,这便是Spring Boot的自动配置功能。先从整体上看一下Spring Boot实现该运作机制涉及的核心部分,如图2-1所示。

        Spring Boot通过@EnableAutoConfiguration注解开启自动配置,加载spring.factories中注册的各种AutoConfiguration类,当某个AutoConfiguration类满足其注解@Conditional指定的生效条件(Starters提供的依赖、配置或Spring容器中是否存在某个Bean等)时,实例化该AutoConfiguration类中定义的Bean(组件等),并注入Spring容器,就可以完成依赖框架的自动配置。 

  • @EnableAutoConfiguration:该注解由组合注解@SpringBootApplication引入,完成自动配置开启,扫描各个jar包下的spring.factories文件,并加载文件中注册的AutoConfiguration类等。
  • spring.factories:配置文件,位于jar包的META-INF下,按照指定格式注册了自动配置的AutoConfiguration类。spring.factories也可以包含其他类型待注册的类。该配置文件不仅存在于Spring Boot项目中,也可以存在于自定义的自动配置(或Starter)项目中。
  • AutoConfiguration类:自动配置类,代表了Spring Boot中一类以XXAutoConfiguration命名的自动配置类。其中定义了三方组件集成Spring所需初始化的Bean和条件。
  • @Conditional:条件注解及其衍生注解,在AutoConfiguration类上使用,当满足该条件注解时才会实例化AutoConfiguration类。
  • Starters:三方组件的依赖及配置,Spring Boot已经预置的组件。Spring Boot默认的Starters项目往往只包含了一个pom依赖的项目。如果是自定义的starter,该项目还需包含spring.factories文件、AutoConfiguration类和其他配置类。

2.2 运作原理源码解析之@EnableAutoConfiguration

        @EnableAutoConfiguration是开启自动配置的注解,是由组合注解@SpringBootApplication引入的。

2.2.1 入口类和@SpringBootApplication注解

        Spring Boot项目创建完成会默认生成一个*Application的入口类,入口类的命名规则都是artifactId+Application。通过该类的main方法即可启动Spring Boot项目,代码如下。

         @SpringBootApplication部分源代码如下:

        通过以上源代码发现,Spring Boot中大量使用了@AliasFor注解,该注解用于桥接到其他注解,该注解的属性中指定了所桥接的注解类。如果点进去查看,会发现@SpringBootApplication定义的属性在其他注解中已经定义过。之所以使用@AliasFor注解并重新在@SpringBootApplication中定义,更多是为了减少用户使用多注解带来的麻烦。

        @SpringBootConfiguration并在其内组合了@Configuration。@EnableAutoConfiguration注解组合了@AutoConfigurationPackage。

2.2.2 注解@EnableAutoConfiguration功能解析

        在未使用Spring Boot的情况下,Bean的生命周期由Spring来管理,然而Spring无法自动配置@Configuration注解的类。Spring Boot的核心功能之一就是根据约定自动管理该注解标注的类。用来实现该功能的组件之一便是@EnableAutoConfiguration注解。

        @EnableAutoConfiguration的主要功能是启动Spring应用程序上下文时进行自动配置,它会尝试猜测并配置项目可能需要的Bean。自动配置通常是基于项目classpath中引入的类和已定义的Bean来实现的。在此过程中,被自动配置的组件来自项目自身和项目依赖的jar包中。

@EnableAutoConfiguration的主要功能是启动Spring应用程序上下文时进行自动配置,它会尝试猜测并配置项目可能需要的Bean。自动配置通常是基于项目classpath中引入的类和已定义的Bean来实现的。在此过程中,被自动配置的组件来自项目自身和项目依赖的jar包中。

        @EnableAutoConfiguration注解的源码:

        需要注意的是,被@EnableAutoConfiguration注解的类所在package还具有特定的意义,通常会被作为扫描注解@Entity的根路径。这也是在使用@SpringBootApplication注解时需要将被注解的类放在顶级package下的原因。而对于入口类和其main方法来说,并不依赖@SpringBootApplication注解或@EnableAutoConfiguration注解,也就是说该注解可以使用在其他类上,而非入口类上。

2.3 AutoConfigurationImportSelector源码解析

        @EnableAutoConfiguration的关键功能是通过@Import注解导入的ImportSelector来完成的。从源代码得知@Import(AutoConfigurationImportSelector.class)是@EnableAutoConfiguration注解的组成部分,也是自动配置功能的核心实现者。@Import(AutoConfigurationImportSelector.class)又可以分为两部分:@Import和对应的ImportSelector。

2.3.1 @Import注解

        @Import注解位于spring-context项目内,主要提供导入配置类的功能。

        @Import的作用和xml配置中<import/>标签的作用一样,可通过@Import引入@Configuration注解的类,也可以导入实现了ImportSelector或ImportBeanDefinitionRegistrar的类,还可以通过@Import导入普通的POJO(将其注册成Spring Bean,导入POJO需要Spring 4.2以上版本)。

2.3.2 ImportSelector接口

        @Import的许多功能都需要借助接口ImportSelector来实现,ImportSelector决定可引入哪些@Configuration。ImportSelector接口源码如下。

         ImportSelector接口提供了一个参数为AnnotationMetadata的方法,返回的结果为一个字符串数组。其中参数AnnotationMetadata内包含了被@Import注解的类的注解信息。在selectImports方法内可根据具体实现决定返回哪些配置类的全限定名,将结果以字符串数组的形式返回。

        ImportSelector接口只提供了一个参数为AnnotationMetadata的方法,返回的结果为一个字符串数组。参数AnnotationMetadata内包含了被@Import注解的类的注解信息。在selectImports方法内可根据具体实现决定返回哪些配置类的全限定名,将结果以字符串数组的形式返回。

        在AutoConfigurationImportSelector的源代码中就实现了这4个接口:

        AutoConfigurationImportSelector实现了ImportSelector接口的子接口DeferredImportSelector。DeferredImportSelector接口与ImportSelector的区别是,前者会在所有的@Configuration类加载完成之后再加载返回的配置类,而ImportSelector是在加载完@Configuration类之前先去加载返回的配置类。DeferredImportSelector的加载顺序可以通过@Order注解或实现Ordered接口来指定。同时,DeferredImportSelector提供了新的方法getImportGroup()来跨DeferredImportSelector实现自定义Configuration的加载顺序。 

2.3.3 AutoConfigurationImportSelector功能概述

        从整体上了解AutoConfigurationImportSelector的核心功能及流程,然后再对照代码看具体的功能实现。图2-3中省略了外部通过@Import注解调用该类的部分。

         当AutoConfigurationImportSelector被@Import注解引入之后,它的selectImports方法会被调用并执行其实现的自动装配逻辑。

2.3.4 @EnableAutoConfiguration自动配置开关 

        检查自动配置是否开启,如果开启自动配置功能,就继续执行后续操作;如果未开启,就返回空数组。代码如下。

        EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY的配置,该常量的值为spring.boot.enableautoconfiguration。如果获取不到该属性的配置,isEnabled默认为true,也就是默认会使用自动配置。如果当前类为其他类,直接返回true。

        在application.properties或application.yml中针对此参数进行配置。以application.properties配置关闭自动配置为例,代码如下。

 2.3.5 @EnableAutoConfiguration加载元数据配置

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/212436
推荐阅读
相关标签
  

闽ICP备14008679号