Spring Boot由众多Starter组成,随着版本的推移Starter家族成员也与日俱增。在传统Maven项目中通常将一些层、组件拆分为模块来管理, 以便相互依赖复用,在Spring Boot项目中我们则可以创建自定义Spring Boot Starter来达成该目的。
1. 创建一个 maven 工程
pom 文件如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.majm</groupId>
<artifactId>sample-spring-boot-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>sample-spring-boot-starter</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- @ConfigurationProperties annotation processing (metadata for IDEs)
生成spring-configuration-metadata.json类,需要引入此类-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
</dependencies>
</project>
注意 依赖 spring-boot-configuration-processor
是为了在编译时生成 spring-configuration-metadata.json
文件,此文件主要是给 IDE 使用,用于提示使用。
example: 如在Intellij idea
中,当配置此 jar 相关配置属性在application.yml
,你可以用cmd + 鼠标左键
,IDE会跳转到你配置此属性的类中。
这里说一下 artifactId 命名问题, spring 官方Start 通用命名规则为 spring-boot-starter-{name}
spring 官方建议非官方 start 命名规范 {name}-spring-boot-starter
2. 编写 Service
/**
* 业务类 </br>
*
* @author majunmin
* @description
* @datetime 2019-07-04 17:59
* @since
*/
@AllArgsConstructor
public class ExampleService {
private String name;
private String desc;
public String desc(){
return name + ":" + desc;
}
}
3. 编写属性类
/**
* 属性类 </br>
*
* @author majunmin
* @description
* @datetime 2019-07-04 17:53
* @since
*/
@Getter
@Setter
@ConfigurationProperties("com.service")
public class ExampleProperties {
private String name;
private String desc;
}
4. 编写自动配置类
/**
* 自动配置类 </br>
*
* 1. @ConditionalOnClass,当classpath下发现该类的情况下进行自动配置。
* 2. @ConditionalOnMissingBean,当Spring Context中不存在该Bean时。
* 3. @ConditionalOnProperty(prefix = "example.service",value = "enabled",havingValue = "true"),当配置文件中example.service.enabled=true时。
*
* @author majunmin
* @description
* @datetime 2019-07-04 17:57
* @since
*/
@Configuration
@ConditionalOnClass(ExampleService.class)
@EnableConfigurationProperties(ExampleProperties.class)
public class ExampleAutoConfig {
private final ExampleProperties exampleProperties;
@Autowired
public ExampleAutoConfig(ExampleProperties exampleProperties) {
this.exampleProperties = exampleProperties;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "example.service", value = "enabled", havingValue = "true")
ExampleService exampleService(){
return new ExampleService(exampleProperties.getName(), exampleProperties.getDesc());
}
}
5. 添加spring.factories
在resources/META-INF/
下创建 spring.factories
文件
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.majm.config.ExampleAutoConfig
ok 完成, 执行 mvn clean install -DskipTests
,打包安装到本地
6. Test
好了 来测试一下。
另外创建一个SpringBoot工程,在maven中引入这个starter依赖, 然后在单元测试中引入这个Service看看效果。
pom文件 引入依赖
···xmlcom.majm sample-spring-boot-starter 1.0.0-SNAPSHOT 在
application.yml
中 添加属性com.service: enabled: true name: aaa desc: bbb
编写 Controller
@Autowired
private ExampleService exampleService;
@GetMapping("/test")
public Object getUser() {
return exampleService.desc();
}
返回结果如下
OK!
总结
总结下Starter的工作原理:
- Spring Boot在启动时扫描项目所依赖的JAR包,寻找包含
spring.factories
文件的JAR包 - 根据
spring.factories
配置加载AutoConfigure类 - 根据
@Conditional
注解的条件,进行自动配置并将Bean注入Spring Context