Spring Boot创建自定义starter

Spring Boot中,starter是为快速应用开发提供“一站式服务”的依赖(Dependency)。starter使得开发人员在开始编写新的模块时不需要拷贝样板式的配置文件、编写样板式的代码,只需要提供最简单的配置(比如host & port)即可开始编程。

本文基于Spring Boot 1.4.8编写

命名

Spring Boot使用spring-boot-starter-作为官方starters的命名前缀,并且建议非Spring Boot内部的starter使用其他前缀以示区分。

引导机制

Spring Boot使用注解代替xml配置文件配置应用上下文,称之为auto-configuration。在提供自己的组件时,Spring Boot不会自己来扫描所有的包,而是通过读取classpath下META-INF/spring.factories文件中配置的类来开始加载流程。这可以视为Spring Boot的引导机制。

spring.factories中,可以配置:

  1. org.springframework.boot.autoconfigure.EnableAutoConfiguration 自动配置类
  2. org.springframework.context.ApplicationContextInitializer 实现该接口可以自定义窗口启动早期的初始化行为
  3. org.springframework.context.ApplicationListener 实现该接口可以监听容器事件

配置键是接口或注解的全名,配置值是实现类或目标类的全名。在spring.factories中配置的类,都会被spring容器加载并实例化为spring beans。

此处只列举了最常用的几个配置项,更多功能可以参考Spring Boot内部的配置文件

自动配置

一般来说,自动配置类可以命名为*AutoConfiguration。在自动配置类中,常用的配置注解有:

  • @Import 加载指定类
  • @ComponentScan/@ComponentScan.Filter 配置自动扫描的包名、支持使用内置或自定义过滤器,最常见的是
  • @EnableConfigurationProperties 自动加载配置项并反射到ConfigurationProperties bean中
  • @PropertySource 配置属性源,可以用于自定义的配置文件
  • @Bean 提供默认配置的bean

条件配置

Spring Boot支持在@Configuration@Bean上使用条件注解(Condition annotations),在程序实际运行时动态判定初始化行为。比如根据某配置项、某个类是否存在判断是否判断是否加载某个bean。

  • @ConditionalOnClass/@ConditionalOnMissingClass 根据类的存在性判定
  • @ConditionalOnBean/@ConditionalOnMissingBean 根据bean的存在性判定
  • @ConditionalOnProperty 根据配置项的存在性判定
  • @ConditionalOnResource 根据文件的存在性判定
  • @ConditionalOnWebApplication/@ConditionalOnNotWebApplication 根据是否为Web应用判定
  • @@ConditionalOnExpression 根据Spring EL判定

基于“约定优于配置”的思想,条件注解可以用来根据实际情况灵活地配置自己的组件。比如使用@ConditionalOnClass,探测到程序中存在com.mysql.jdbc.Driver类,就可以视为应用使用MySQL作为数据源,可以自动配置MySQL相关的功能;比如使用@ConditionalOnProperty可以根据程序实际的配置项来决定初始化行为。

配置元数据

Spring Boot可以通过在jar包里提供配置元数据,让IDE具备智能提示和自动完成配置项的功能。Spring Boot提供了spring-boot-configuration-processor模块,依赖了该模块以后,在项目compile阶段processor会扫描本项目中所有带@ConfigurationProperties注解的类,并为其每一个配置项字段(具有setter)生成配置元数据,存放在jar包的META-INF/spring-configuration-metadata.json文件中。

1
2
3
4
5
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

optional为true,可以使得spring-boot-configuration-processor的依赖不向上传播。

对于@ConfigurationProperties注解的类中嵌套的不具有ConfigurationProperties注解的POJO,可以在该POJO的字段上使用@NestedConfigurationProperty注解关联起来。

还可以在项目的src/main/resources/META-INF/additional-spring-configuration-metadata.json文件中额外配置元数据,比如配置某个字段允许出现的值范围,IDE可以自动提供自动完成功能。additional-spring-configuration-metadata.json文件中的内容会在compile阶段合并至spring-configuration-metadata.json中。

关于additional-spring-configuration-metadata.json的写法,可以参考Spring Boot文档

元数据仅用于IDE的智能提示,在运行时不造成影响。

参考资料

Spring Boot Reference Guide
Starters
Creating your own auto-configuration