首页 体育 教育 财经 社会 娱乐 军事 国内 科技 互联网 房产 国际 女人 汽车 游戏

手把手教你定制标准Spring Boot starter,真的很清晰

2019-12-18

咱们每次构建一个 Spring 使用程序时,咱们都不期望从头开始完结具有「横切关注点」的内容;相反,咱们期望一次性完结这些功用,并依据需求将它们包括到任何咱们要构建的使用程序中

横切关注点: 指的是一些具有横越多个模块的行为

说白了便是多个项目或模块都能够用到的内容,比方一个 SDK

在Spring Boot中,用于表明供给这种横切关注点的模块的术语是 starter ,经过依靠 starter 能够轻松运用其包括的一些功用特性, 不管你的工作中是否会构建自己的 starter,你都要具有构建 「starter」的思维 ,本文将结合 Spring Boot 官方规范构建一个简略的 starter

在咱们深化了解怎么自界说 starter 之前,为了更好的了解咱们每一步在干什么,以及 starter 是怎么起效果的,咱们先从微观视点来看 starter 的结构组成到底是什么样的

一般一个完好的 starter 需求包括下面两个组件:

假如你看下面这两个组件的解说有些笼统,大约了解一下,阅读完该文章回看这儿就会恍然大悟了

Auto-Configure Module 是包括主动装备类的 Maven 或 Gradle 模块。经过这种方法, 咱们能够构建能够主动奉献于使用程序上下文的模块,以及增加某个特性或供给对某个外部库的拜访

Spring Boot Starter 是一个 Maven 或 Gradle 模块,其仅有意图是供给 发动 某个特性所需的一切依靠项。能够包括一个或多个 Auto-Configure Module 的依靠项,以及或许需求的任何其他依靠项。这样,在Spring 发动使用程序中,咱们只需求增加这个 starter 依靠就能够运用其特性

:warning:: Spring 官方参考手册主张将主动装备别离,并将每个主动装备发动到一个独立的 Maven 或 Gradle 模块中,然后将主动装备和依靠项办理别离开来。假如你没有树立一个供不计其数用户运用的开源库,也能够将二者合并到一个 module 中

You may combine the auto-configuration code and the dependency management in a single module if you do not need to separate those two concerns

来自 Spring 官方的 starter 都是 以 spring-boot-starter 最初,比方:

假如咱们自界说 starter 功用称号叫 acme ,那么咱们的命名是这样的:

假如 starter 顶用到了装备 keys,也要留意不要运用 Spring Boot 运用的命名空间,比方

先来大局看一下项目结构:

一级目录结构:

.
├── pom.xml
├── rgyb-spring-boot-autoconfigure
├── rgyb-spring-boot-sample
└── rgyb-spring-boot-starter

二级目录结构:

.
├── pom.xml
├── rgyb-spring-boot-autoconfigure
│ ├── pom.xml
│ └── src
├── rgyb-spring-boot-sample
│ ├── pom.xml
│ └── src
└── rgyb-spring-boot-starter
 ├── pom.xml
 └── src

创立一个空的父亲 Maven Module,首要供给依靠办理,这样 SubModule 不用独自保护依靠版本号,来看 pom.xml 内容:

 dependencyManagement 
 dependencies 
 dependency 
 groupId org.springframework.boot /groupId 
 artifactId spring-boot-dependencies /artifactId 
 version ${spring-boot.version} /version 
 type pom /type 
 scope import /scope 
 /dependency 
 /dependencies 
 !-- 增加其他大局依靠办理到这儿,submodule默许不引进这些依靠,需求显式的指定 -- 
 /dependencyManagement 

新建类 GreetingAutoConfiguration

@Configuration
public class GreetingAutoConfiguration {
 @Bean
 public GreetingService greetingService{
 return new GreetingService);
}

咱们用 @Configuration 注解符号类 GreetingAutoConfiguration,作为 starter 的进口点。这个装备包括了咱们需求供给starter特性的一切 @Bean 界说,在本例中,为了简略论述问题,咱们只将 GreetingService Bean 增加到使用程序上下文

GreetingService 内容如下:

@AllArgsConstructor
public class GreetingService {
 private List String members = new ArrayList ;
 public void sayHello{
 members.forEach);
}

在 resources 目录下新建文件 META-INF/spring.factories ,向文件写入内容:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
 top.dayarch.autoconfigure.GreetingAutoConfiguration

Spring 发动时会在其 classpath 中一切的 spring.factoreis 文件,并加载里边的声明装备,GreetingAutoConfiguration 类安排妥当后,咱们的 Spring Boot Starter 就有了一个主动激活的进口点

到这儿这个 不完全的 starter 现已能够运用了。但由于它是主动激活的,为了个让其灵敏可用,咱们需求让其依照咱们的志愿来激活运用,所以咱们需求条件注解来帮助

为类增加两个条件注解:

@Configuration
@ConditionalOnProperty
@ConditionalOnClass
public class GreetingAutoConfiguration {
}

多个条件是 and/与 的联系,既只要满意悉数条件时,才会加载 GreetingAutoConfiguration

假如你对条件注解的运用还不是很清晰,能够检查我之前的文章: @Conditional注解,灵敏装备 Spring Boot

上面运用了 @ConditionalOnProperty 注解,实践 starter 中或许有十分多的特点,所以咱们需求将这些特点会集办理:

@Data
@ConfigurationProperties
public class GreetingProperties {
 * GreetingProperties 开关
 boolean enable = false;
 * 需求打招呼的成员列表
 List String members = new ArrayList ;
}

咱们知道这些特点是要在 application.yml 中运用的,当咱们需求运用这些特点时,为了让 IDE 给出更友爱的提示,咱们需求在 pom.xml 中增加依靠:

 dependency 
 groupId org.springframework.boot /groupId 
 artifactId spring-boot-configuration-processor /artifactId 
 optional true /optional 
 /dependency 

这样当咱们 mvn compile 时,会在生成一个名为 spring-configuration-metadata.json JSON 文件,文件内容如下:

生成的内容在接下来的内容顶用到,且看

关于类途径上的每个主动装备类,Spring Boot 有必要核算 @Conditional… 条件值,用于决议是否加载主动装备及其所需的一切类,依据 Spring 发动使用程序中 starter 的巨细和数量,这或许是一个十分贵重的操作,并且会影响发动时刻,为了提高发动时刻,咱们需求在 pom.xml 中增加别的一个依靠:

 dependency 
 groupId org.springframework.boot /groupId 
 artifactId spring-boot-autoconfigure-processor /artifactId 
 optional true /optional 
 /dependency 

这个注解会生成一个名为 spring-autoconfigure-metadata.properties Property 文件,其内容如下:

这样,Spring Boot 在发动期间读取这些元数据,能够过滤出不满意条件的装备,而不用实践检查这些类,提高发动速度

到这儿关于 Auto-Configure Module 就构建完了,咱们需求持续完结 Starter Module 的构建

Starter Module 的构建很简略了,你能够以为它便是一个空 module,除了依靠 Auto-Configure Module,其仅有效果便是为了运用 starter 功用特性供给一切有必要依靠,所以咱们为 starter module 的 pom.xml 文件增加如下内容:

 dependencies 
 dependency 
 groupId top.dayarch.learnings /groupId 
 artifactId rgyb-spring-boot-autoconfigure /artifactId 
 version 1.0.0.RELEASE /version 
 /dependency 
 !-- 在此处增加其他必要依靠,确保starter可用 -- 
 /dependencies 

同样在 resources 目录下新建文件 META-INF/spring.providers , 其内容如下:

providers: rgyb-spring-boot-autoconfigure

该文件首要效果是阐明 starter module 的依靠信息,多个依靠以逗号分隔就好,该文件不会影响 starter 的运用,可有可无

Starter Module 就能够这么简略,将两个 module 别离 mvn install 到本地 Maven Repository,接下来咱们创立 sample module 引进这个 starter 依靠时就会从本地 Maven Repository 中拉取

咱们能够经过 Spring Initializr 正常初始化一个 Spring Boot 项目 ,引进咱们刚刚创立的 starter 依靠,在 sample pom.xml 中增加依靠:

 dependency 
 groupId top.dayarch.learnings /groupId 
 artifactId rgyb-spring-boot-starter /artifactId 
 version 1.0.0.RELEASE /version 
 /dependency 

接下来装备 application.yml 特点

rgyb:
 greeting:
 enable: true
 members:
 - 李雷
 - 韩梅梅

在咱们装备 YAML 的时分,会出现下图的提示,这样会更友爱,当然为了规范,特点描绘最好也用英文描绘,这儿为了阐明问题用了中文描绘:

咱们编写测验用例:

@Autowired
private GreetingService greetingService;
@Test
public void testGreeting {
 greetingService.sayHello;
}

测验成果如下:

hello 李雷
hello 韩梅梅

到这儿完好的 starter 开发就完毕了,期望咱们了解其构建进程,目录结构及命名等规范,这样有相应的事务需求时都能够开发自己的 starter 被其他人使用起来

starter 开发好了,他人能够手动增加依靠引进 starter 的相关功用,那咱们怎么像 Spring Initializr 相同,经过下来菜单挑选咱们的 starter 呢,这样直接初始化好整个项目,接下来的文章咱们会仿照 Spring Initializr 自界说咱们自的 Initializr

为什么 Auto-Configure Module 的 dependency 都是 optional = true 呢?

这涉及到 Maven 传递性依靠的问题,概况请看 Maven 依靠传递性透彻了解

Spring Boot 是怎么加载这个文件并找到咱们的装备类的

下图是 Spring Boot 使用程序发动的调用栈的一部分,我增加了断点:

翻开 SpringFactoriesLoader 类,映入眼帘的便是这个内容:

这两张图应该满足阐明问题了,是 SPI 的一种加载方法,更细节的内容请咱们自己去发现吧

这儿引荐检查 mybatis-spring-boot-starter 这个非 Spring 官方的事例,从中咱们:

别的,本文的事例我已上传,大众号回复「demo」,翻开链接,检查 customstarter 目录下内容即可

热门文章

随机推荐

推荐文章