https://docs.spring.io/spring-boot/docs/2.5.x/reference/html/features.html#features.developing-auto-configuration https://docs.spring.io/spring-boot/docs/2.5.x/reference/html/features.html#features.developing-auto-configuration.custom-starter https://github.com/snicoll/spring-boot-master-auto-configuration
一个自定义的starter应该有一下几个模块
autoconfigure模块, 包含了自动装配的代码starter模块, 提供了正常功能需要的依赖, 此依赖由autoconfigure模块来进行装配
0.示例
https://gitee.com/spitman/my-starter
1. 命名
- 项目不要以 
spring-boot作为开头, 未来可能会和spring官方的starter起冲突 
经验法则:  假设你在为 acme 业务编写starter, 那么你应该这样起名
autoconfigure模块 :acme-spring-bootstarter模块 :acme-spring-boot-starter
如果autoconfigure模块没有也行, 直接将自动装配的代码写到starter模块中
1.1 多种feature的项目
将starter分为feature和starter两个模块不是必须的, 
如果 acme 具有多种可选特性feature, 那么最好把autoconfigure模块与starter模块分开
然后每个feature, 创建一个starter
例如:
- redis模块的starter: acme-spring-boot-starter-redis
 - jpa模块的starter: acme-spring-boot-starter-jpa
 - mq模块的starter: acme-spring-boot-starter-mq
 
所有feature的自动装配代码都放入 autoconfigure模块中
所有starter都依赖autoconfigure模块, 但是各个starter只引入该feature功能需要的依赖
例如:
- acme-spring-boot-starter-redis: 依赖 autoconfigure模块, 和 jedis
 - acme-spring-boot-starter-jpa: 依赖 autoconfigure模块, 和 jpa
 - acme-spring-boot-starter-mq: 依赖 autoconfigure模块, 和 mq
 
这样其他应用引入你自定义的starter的时候可以更清晰的确定引入的功能
- autoconfigure项目中的各种feature的Maven依赖设置为 
true 的, 然后将所有的starter的自动装配代码写在此项目中 - 具体的 starter 模块提供真正的feature依赖
 
这样autoconfigure中的配置, 可以按应用的依赖的starter进行有选择的加载
1.2 只有一种feature的项目
但如果**autoconfigure**和**starter**不区分可选特性, 那么直接合并为一个**starter**工程也是非常好的选择
2. autoconfigure 模块
autoconfigure模块包含:
- 配置项
 - 自动装配代码
 - maven依赖
 
2.1 定义配置项
一般每个starter都会有自己需要的配置项, 
这些配置项使用方可以在application.properties中赋值配置项的key, 
不要使用 Spring Boot 常用的键 (such as server, management, spring, and so on)未来保不齐spring新的配置项就和你重复了
经验法则:
前缀最好使用你项目的名字, 
比如acme , 
确保你的配置项都有文档, 并对每个属性添加了javadoc, 这样添加 spring-boot-configuration-processor 依赖的时候, 编译时会自动生成 META-INF/spring-autoconfigure-metadata.properties文件, 
使用方的IDE会读取META-INF/spring-autoconfigure-metadata.properties文件 在给配置项赋值的时候会给提示
下面有个例子:
import java.time.Duration;import org.springframework.boot.context.properties.ConfigurationProperties;@ConfigurationProperties("acme")public class AcmeProperties {/*** Whether to check the location of acme resources.*/private boolean checkLocation = true;/*** Timeout for establishing a connection to the acme server.*/private Duration loginTimeout = Duration.ofSeconds(3);public boolean isCheckLocation() {return this.checkLocation;}public void setCheckLocation(boolean checkLocation) {this.checkLocation = checkLocation;}public Duration getLoginTimeout() {return this.loginTimeout;}public void setLoginTimeout(Duration loginTimeout) {this.loginTimeout = loginTimeout;}}
2.2 自动装配代码
自动装配的代码, 也就是各种 @Configuration, @ConditionalOnXXX 配置的java类
示例:
/*** 一个最简单的 自动装配的配置类*/@ConditionalOnClass(MyWeirdBean.class)@Configuration@EnableConfigurationProperties(MyConfigurationProperties.class)public class MyWeirdBeanAutoConfiguration {@Autowiredprivate MyConfigurationProperties myConfigurationProperties;@Bean("bean1")@ConditionalOnMissingBean(MyWeirdBean.class)public MyWeirdBean getMyWeirdBean() {return new MyWeirdBean(myConfigurationProperties.getThings());}}
所有feature的自动装配代码都写在autoconfigure模块中
为了让这些配置类能够在starter启动的时候加载, 需要在autoconfigure模块中配置 META-INF/spring.factories 文件, 告诉spring启动的时候主动加载这些配置类
示例:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.example.config.MyWeirdBeanAutoConfiguration,\com.example.config.MyOtherBeanAutoConfiguration
2.3 maven依赖
必须的maven依赖:
正常情况下autoconfigure模块中的其他feature的maven依赖一般需要标记为 <optional>true</optional>
这样starter模块引入autoconfigure 模块 只要提供依赖就加载配置, 不提供依赖则不加载配置, 调用方使用起来会非常方便
示例:
注意: 如果在应用中直接定义 autoconfigure模块的功能, 则需要配置 spring-boot-maven-plugin 防止repackage操作将依赖引入jar文件
<project><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure-processor</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>
3. starter模块
starter模块 编译后就是个空jar包
它存在的目的就是 提供自动装配必需的依赖 , 也就是说它一般只有一个pom.xml文件
4. 使用starter
使用方直接引入starter依赖即可
