共计 4164 个字符,预计需要花费 11 分钟才能阅读完成。
SpringBoot 的核心就是自动配置,而支持自动配置的是一个个 starter 项目。除了官方已有的 starter,用户自己也可以根据规则自定义自己的 starter 项目。
自定义 starter 条件
自动化配置需满足以下条件:
- 根据条件检查 classpath 下对应的类,也就是说需要提供对应可检查的类;
- 当满足条件时能够生成定义的 Bean,并注册到容器中去;
- 能够自动配置项目所需要的配置;
自定义 spring boot starter
这里通过 maven 项目管理工具进行 starter 的创建。首先我们需要创建一个简单的 maven 项目。这里我们以集成某短信服务为例,来创建一个项目。
创建 maven 项目
创建一个简单的 maven 项目,具体步骤省略。可通过 intellj idea 等 IDE 进行创建,也可通过 maven 命令进行创建。
目录结构如下:
.
├── pom.xml
├── spring-boot-starter-msg.iml
└── src
├── main
└── test
在 pom.xml 中引入 SpringBoot 自动化配置依赖 spring-boot-autoconfigure:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
定义 Service 服务类
定义 Service 服务类,有两个作用,一个为引入的项目本省的功能性服务,另外一个用来 springboot 自动配置时的判断依据。
这里定义一个 MsgService 的类。
package com.secbro2.msg;
import com.secbro2.utils.HttpClientUtils;
public class MsgService {
/**
* 访问发送短信的 url 地址
*/
private String url;
/**
* 短信服务商提供的请求 keyId
*/
private String accessKeyId;
/**
* 短信服务商提供的 KeySecret
*/
private String accessKeySecret;
public MsgService(String url, String accessKeyId, String accessKeySecret) {
this.url = url;
this.accessKeyId = accessKeyId;
this.accessKeySecret = accessKeySecret;
}
public int sendMsg(String msg) {
// 调用 http 服务并发送消息,返回结果
return HttpClientUtils.sendMsg(url, accessKeyId, accessKeySecret, msg);
}
// 省略 getter/setter 方法
}
其中 MsgService 用到了一个工具类 HttpClientUtils。在 HttpClientUtils 中只简单打印了请求的参数信息。
package com.secbro2.utils;
public class HttpClientUtils {public static int sendMsg(String url, String accessKeyId, String accessKeySecret, String msg) {
//TODO 调用指定 url 进行请求的业务逻辑
System.out.println("Http 请求,url=" + url + ";accessKeyId=" + accessKeyId + ";accessKeySecret=" + accessKeySecret + ";msg=" + msg);
return 0;
}
}
定义配置类
定义 MsgProperties 配置类,用于封装 application.properties 或 application.yml 中的基础配置。这里关于短信发送的配置前缀统一采用 msg。
@ConfigurationProperties(prefix = "msg")
public class MsgProperties {
/**
* 访问发送短信的 url 地址
*/
private String url;
/**
* 短信服务商提供的请求 keyId
*/
private String accessKeyId;
/**
* 短信服务商提供的 KeySecret
*/
private String accessKeySecret;
// 其他参数定义
// 省略 getter/setter 方法
}
通过 @ConfigurationProperties 注解来进行对应的属性的装配。
创建自动化配置类
自动配置类就是一个普通的 java 类,通过不同的注解来对其赋予不同的功能。其中最核心的当然是 @Configuration 注解。
@Configuration
@ConditionalOnClass(MsgService.class)
@EnableConfigurationProperties(MsgProperties.class)
public class MsgAutoConfiguration {
/**
* 注入属性配置类
*/
@Resource
private MsgProperties msgProperties;
@Bean
@ConditionalOnMissingBean(MsgService.class)
@ConditionalOnProperty(prefix = "msg", value = "enabled", havingValue = "true")
public MsgService msgService() {MsgService msgService = new MsgService(msgProperties.getUrl(), msgProperties.getAccessKeyId(),
msgProperties.getAccessKeySecret());
// 如果提供了其他 set 方法,在此也可以调用对应方法对其进行相应的设置或初始化。return msgService;
}
}
MsgAutoConfiguration 类上的注解,@Configuration 用来声明该类为一个配置类;@ConditionalOnClass 注解说明只有当 MsgService 类存在于 classpath 中时才会进行相应的实例化;@EnableConfigurationProperties 将 application.properties 中对应的属性配置设置于 MsgProperties 对象中;
msgService 方法上的注解,@Bean 表明该方法实例化的对象会被加载到容器当中;@ConditionalOnMissingBean 指明当容器中不存在 MsgService 的对象时再进行实例化;@ConditionalOnProperty 指定了配置文件中 msg.enabled=true 时才进行相应的实例化。
添加 spring.factories
当所有的基础代码和自动配置类都准备完成,就需要对其进行注册。也就是我们熟悉的 META-INF/spring.factories 配置文件了。当然,这个需要在自己的项目中进行创建。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.secbro2.msg.MsgAutoConfiguration
在 spring.factories 配置文件中注册 MsgAutoConfiguration 类。如果有多个自动配置类,用逗号分隔换行即可。
至此,一个基于 Spring Boot 的自动配置 starter 便完成了。使用“maven:install”将其打包到本地 maven 仓库或上传至私服。其他项目便可以通过 maven 依赖使用。
starter 项目使用
在其他项目中,通过以下依赖引入该依赖。
<dependency>
<groupId>com.secbro2</groupId>
<artifactId>spring-boot-starter-msg</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
然后在当前项目的 application.properties 中配置对应的参数:
msg.enabled=true
msg.url=127.0.0.1
msg.accessKeyId=10001
msg.accessKeySecret=afelwjfwfwef
比如其他项目同样是 Spring Boot 项目,则可定义一个简单的 Controller 来进行测试。
@RestController
public class HelloWorldController {
@Resource
private MsgService msgService;
@RequestMapping("/sendMsg")
public String sendMsg(){msgService.sendMsg("测试消息");
return "";
}
}
当通过浏览器访问:http://localhost:8080/sendMsg 时,便会打印出如下日志:
Http 请求,url=127.0.0.1;accessKeyId=10001;accessKeySecret=afelwjfwfwef;msg= 测试消息
说明 MsgService 对象被自动配置,并且测试通过。
而针对短信发送这样的 starter,可以进行进一步拓展,实现短信发送的各种基础功能,而当其他项目需要时只用引入对应的依赖,并配置具体的参数即可马上使用,是不是非常方便?
总结下 Starter 的工作流程:
- Spring Boot 在启动时扫描项目所依赖的 JAR 包,寻找包含 spring.factories 文件的 JAR 包;
- 根据 spring.factories 配置加载 AutoConfiguration 类;
- 根据 @Conditional 注解的条件,进行自动配置并将 Bean 注入 Spring 容器。
<center> 程序新视界 :精彩和成长都不容错过 </center>