如何自定义 Spring Boot Starter?今天终于学会了~
本篇主要讲述 Spring Boot Starter 的概念、命名规范,以及如何自定义一个 Starter,下面开始今天的内容。
1 Starter 是什么
Spring Boot 的 Starter 是一组比较方便的依赖描述符,可以通过 Maven 将其打成jar
包,并在你的项目中直接引用。
通过 Starter 你可以获取该功能的所有依赖,以及统一的配置,避免了复制、粘贴代码和依赖带来的麻烦。
Starter 主要使用了自动配置,所以它下面的所有组件会被 Spring Boot 通过META-INF/spring.factories
文件注入IOC容器中。
2 命名规范
2.1 Starter 项目的命名规范
所有由Spring官方提供的Starter都会遵循spring-boot-starter-*
的命名规范,其中*
表示特定类型的应用程序。
而所有第三方的Starter,官方建议以项目名称开头,应遵循*-spring-boot-starter
的命名规范,其中*
表示第三方项目名称。
2.2 配置项的命名规范
如果自定义的 Starter 包含了配置项,请为它使用唯一的命名空间,不要与 Spring Boot 或其他组件产生冲突,例如:server
、management
、spring
等
3 自定义一个 Starter
一个典型的 Starter 包含自动配置和自定义的核心代码。为了演示方便,本例中的核心代码就是一个“宠物”类,能够根据配置的“类型”来获取对应的“宠物”,下面看具体实现过程。
3.1 创建自定义的 Starter 工程
创建一个 Spring Boot 工程,将其命名为demo-spring-boot-starter
。下图是工程完整目录结构,后面会逐一介绍它们。
3.2 POM中引入相关依赖
在POM中引入两个依赖:
spring-boot-starter
:该依赖是 Starter 的核心,包括自动配置、日志和YAML的支持。我们所有自定义的 Starter 都应该直接或间接的引入该依赖。spring-boot-configuration-processor
:包含一个 Java 注解处理器,当使用@ConfigurationProperties
注解配置自己的元数据时,需要引入此依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
3.3 定义一个配置元数据类
自定义一个配置元数据类DemoProperties
,用于映射YAML中的配置,使用@ConfigurationProperties
注解需要指定配置项的前缀,此处的前缀为demo
。当前配置项只有一个type
字段,用于配置宠物的类型,那么该配置项的 Key 为:demo.type
。
@ConfigurationProperties(prefix = "demo")
public class DemoProperties {
/**
* 类型
*/
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
3.4 定义一个配置类
先看自定义的宠物实体类Pet
,很简单,只有一个name
属性(此类纯属为了演示 Starter,无它)。
public class Pet {
/**
* 名称
*/
private String name;
public Pet(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
增一个配置类DemoAutoConfiguration
,该类也非常简单:
- 使用
@Configuration
注解声明该类为一个配置类; - 使用
@EnableConfigurationProperties
注解,引入自定义的配置元数据DemoProperties
- 声明了一个
Pet
的 Bean,根据配置项中的type
来返回不同的宠物。使用该 Bean 的目的,主要是用来演示 Starter 的自动配置。
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(DemoProperties.class)
public class DemoAutoConfiguration {
private final DemoProperties demoProperties;
public DemoAutoConfiguration(DemoProperties demoProperties) {
this.demoProperties = demoProperties;
}
@Bean
public Pet pet() {
if (!StringUtils.hasText(demoProperties.getType())) {
return new Pet("空的");
}
switch (demoProperties.getType()) {
case "cat":
return new Pet("小猫");
case "dog":
return new Pet("小狗");
default:
return new Pet("未知");
}
}
}
3.5 定义自动配置的候选
在resources
资源目录中增加文件META-INF/spring.factories
,并将自定义的配置类DemoAutoConfiguration
加入到自动配置类列表中,如下代码:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
io.github.gozhuyinglong.autoconfigure.DemoAutoConfiguration
这一步比较关键,需要重点说一下。
我们自定义Starter 的相关组件,肯定不在使用者自动扫描的目标中(目录结构不同),所以 Spring Boot 提供了这种机制,能够使第三方使用者发现这些组件。
Spring Boot 会检查所有发布的jar
中是否包含META-INF/spring.factories
文件,并将该文件中目标类注入IOC容器中,自动配置类就是使用这种方式加载的。
在上一篇《Spring Boot 自动配置的原理》中已经讲过自动配置的原理了,不了解的老铁建议先看下。
4 使用 Starter
我们再次创建一个工程,用于测试 Starter 是否生效。注意该工程的目录结构要与 Starter 的目录结构不同,这样才能测试出 Starter 中的组件是被 META-INF/spring.factories
文件引入的,而非自动扫描。
4.1 创建一个客户端工程
创建一个 Spring Boot 工程,将其命名为 demo-client
。下图是工程完整目录结构,后面会逐一介绍它们。
4.2 引入自定义 Starter 依赖
在POM文件中,引入刚者自定义的 Starter 依赖。为了便于测试,将spring-boot-starter-web
也引入进来。
<dependency>
<groupId>io.github.gozhuyinglong</groupId>
<artifactId>demo-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
4.3 创建启动类
创建主启动类ClientApplication
,注意该类的目录与 Starter 不同,也就是说当前工程不会通过@ComponentScan
方式自动扫描 Starter 中的组件。
@SpringBootApplication
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
4.4 配置“宠物”的类型
自定义的 Starter 中可以配置宠物的类型,将其配置为dog
。
demo:
type: dog
4.5 创建一个 Controller 类
创建一个ClientController
类,用于测试 Starter 是否生效
@RestController
@RequestMapping("/client")
public class ClientController {
@Autowired
private Pet pet;
@GetMapping("/test")
public String test() {
return pet.getName();
}
}
4.6 测试 Starter
启动项目后,使用 Postman 或直接在浏览器中输入地址:http://127.0.0.1:8080/client/test,会发现输出了“小狗”,表示成功。
5 完整代码
完整代码请访问我的Github,若对你有帮助,欢迎给个⭐,感谢~~🌹🌹🌹
https://github.com/gozhuyinglong/blog-demos/tree/main/springboot-family
- 点赞
- 收藏
- 关注作者
评论(0)