前言
使用SpringBoot的过程中,一定看到过各种 spring-boot-starter 比如第三方扩展的有 druid-spring-boot-starter,mybatis-plus-boot-starte r等,官方的有spring-boot-starter-web 等。这里注意他们的命名规则,第三方扩展的命名规则是 xxx-spring-boot-starter, 官方的命名规则是 spring-boot-starter-xxx。
starter的作用
在业务代码开发中,可以封装一些公用的会在多个项目中使用的工具类,相当于是项目级别的Method,如果公司有中间件团队也是会采用starter这种方式提供给业务团队使用。有效的减少了代码重复硬拷贝以及繁杂的配置,统一集成进starter,也有利于后期版本的迭代管理。
自己实现一个starter
创建 Maven项目
- 根据第三方扩展的命名规则 首先创建一个项目名称为 sms-spring-boot-starter。
- 删除启动(带有@SpringBootApplication)类。
- pom.xml依赖修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <?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"> <parent> <artifactId>hexo-blog-demo</artifactId> <groupId>org.pepsiyoung</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion>
<groupId>com.pepsiyoung</groupId> <artifactId>sms-spring-boot-starter</artifactId>
<properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>
<dependencies> <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> </dependencies> </project>
|
创建 SmsProperties
1 2 3 4 5 6 7 8
| @ConfigurationProperties(prefix = "sms") @Data public class SmsProperties {
private String operator = "电信"; }
|
配合 spring-boot-configuration-processor 能够在开发过程中通过IDE的处理给我们更多的便捷提示。这是因为在项目中包含了meta-data,编译后会在target/classes/META-INF/文件夹下生成spring-configuration-metadata.json,有兴趣的同学可以看下文件目录。
@Data 注解是使用了 Lombok
@ConfigurationProperties(prefix = “sms”) 设置前缀 (sms.operator = xxx)
不需要在resources下创建application.yml文件
创建 Service
- 创建 MessageService 类假装他有一个sms方法能够发送消息。
1 2 3 4 5 6 7 8 9
| private final SmsProperties smsProperties;
public MessageService(SmsProperties smsProperties) { this.smsProperties = smsProperties; }
public String sms(String phone, String content) { return String.format("假装发送[%s]给手机号[%s]的用户「%s」", phone, content, smsProperties.getOperator()); }
|
创建自动配置类
- 创建 AutoConfiguration 类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @EnableConfigurationProperties(SmsProperties.class) @Configuration public class AutoConfiguration {
final SmsProperties smsProperties;
public AutoConfiguration(SmsProperties smsProperties) { this.smsProperties = smsProperties; }
@Bean public MessageService messageService() { return new MessageService(smsProperties); } }
|
- 在resources/META-INF/ 下创建 spring.factories 文件
1
| org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.pepsiyoung.sms.config.AutoConfiguration
|
测试验证
- 在IDEA中,执行mvn install。
- 完成后,在其他项目的pom文件中引入。
1 2 3 4 5 6
| <dependency> <groupId>com.pepsiyoung</groupId> <artifactId>sms-spring-boot-starter</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
|
- 写一个 controller 做测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @RestController @RequestMapping("sms") public class smsController {
@Autowired MessageService messageService;
@GetMapping("test") public String test() { String phone = "18822233344"; String content = "天气变冷"; return messageService.sms(phone, content); } }
|
发现 messageService 能够正常使用 输出结果:假装发送[18822233344]给手机号[天气变冷]的用户「电信」
- 也可以在yml文件中配置sms.operator 如果不设置默认就是电信
再运行 输出结果:假装发送[18822233344]给手机号[天气变冷]的用户「联通」
总结
今天我们了解了 spring-boot-configuration-processor 的作用,并且动手实现了一个自定义starter。过程并不复杂,那是因为spring帮我们做了很多事。spring.factories里配置的类是为了通知 Spring Boot 需要加载哪些自动装配类。Spring boot 中的 starter 是非常重要的机制,抛弃繁杂的配置,统一集成进starter。可以理解为是项目及别的Method。
最后我把完整的代码放在Github上有需要的同学可以start这个项目。
https://github.com/pepsiyoung/hexo-blog-demo/tree/main/sms-spring-boot-starter
如有错误欢迎指正。