有道无术,术尚可求,有术无道,止于术。
本系列Spring Boot版本2.7.0
Spring Boot
提供了很多Starter
包,用起来这么方便,在实际开发过程中使用第三方框架时,可能它并没有继承Spring Boot
,那么我们应该怎么自己实现Spring Boot
自动配置,自定义Starter包呢?
需求场景:比如我们公司现在使用 Minio
作为文件服务器,文件管理服务需要引入minio-java
客户端和文件服务器进行交互操作。
在Minio仓库没有发现集成Spring 相关的包。那么只能自己写了。
首先遇到的问题就是取名了,可以看到Spring Boot
自己开发的都是以spring-boot-starter-xx
的格式。
然后看几个非官网开发的 starter ,都是以xx-spring-boot-starter
的格式,这也是Spring 官网推荐第三方使用的格式。
mybatis-spring-boot-starter
dynamic-datasource-spring-boot-starter
druid-spring-boot-starter
由上决定将项目名称命名为pearl-mino-spring-boot-starter
,加了一个本公司名称前缀,表示是由本公司集成,而非Minio
官方提供。
项目创建完成后,就是该如何定义项目下一级的模块了。还是一样,首先看下Spring Boot
是如何定义的。
Spring Boot
的 Starter包中,只是引入了当前包所需的一些依赖:
自动配置的代码都放在了spring-boot-autoconfigure
模块中:
mybatis
也是一样,将代码全部写在了autoconfigure
模块中, Starter
包只负责依赖管理。
再看下mybatis-plus
,则是将自动配置和依赖管理都放在了一个模块中。
以上这两种方式都可以,多个模块可以将测试、Demo也放在一起,但是考虑到是公司内部使用,不需要搞这么细,为了方便就使用一个模块就可以了。
最后再按照规范创建一个com.pearl.minio.autoconfigure
包,项目结构就搭建完成了。
在POM文件中,添加自动配置、Minio 客户端等依赖:
<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.0modelVersion>
<groupId>com.pearlgroupId>
<artifactId>pearl-minio-spring-boot-starterartifactId>
<version>1.0-SNAPSHOTversion>
<description>Spring Boot Support for Miniodescription>
<inceptionYear>2022inceptionYear>
<properties>
<java.version>1.8java.version>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<spring.boot.version>2.7.0spring.boot.version>
<minio.client.version>8.4.3minio.client.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>${spring.boot.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>io.miniogroupId>
<artifactId>minioartifactId>
<version>8.4.3version>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-autoconfigureartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>io.miniogroupId>
<artifactId>minioartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
exclude>
excludes>
configuration>
plugin>
plugins>
build>
project>
在Minio 官方文档中,通过访问服务地址、账户、密码来创建一个客户端:
所以我们将客户端的这些配置封装为配置类,并写好注释:
@ConfigurationProperties(prefix = "pearl.minio")
public class MinioProperties {
/**
* 是否开启,默认 true
*/
private boolean enabled = true;
/**
* 对象存储服务的URL
*/
private String endpoint;
/**
* 账户
*/
private String accessKey;
/**
* 密码
*/
private String secretKey;
// 省略getter setter....
}
执行mvn 编译,将下图编译出来的文件复制到resources
目录下:
spring-configuration-metadata.json
是由我们之前添加的spring-boot-configuration-processor
包生成的,可以通过@ConfigurationProperties
注解标识的配置类生成配置元数据,放在规定的目录下,我们在IDEA 中添加配置时,会有一个提示功能,这个功能非常方便也是必须的。可以参考Spring Boot官网更细节了解这个功能。
添加自动配置类,使用配置类的属性注入一个Minio 客户端Bean 。
@Configuration
@ConditionalOnClass({MinioClient.class})
@ConditionalOnProperty(prefix = "pearl.minio", name = "enabled", havingValue = "true", matchIfMissing = true)
@EnableConfigurationProperties({MinioProperties.class})
public class MinioAutoConfiguration {
@Bean
MinioClient minioClient(MinioProperties minioProperties) {
MinioClient minioClient = MinioClient.builder()
.endpoint(minioProperties.getEndpoint())
.credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey())
.build();
return minioClient;
}
}
并在resources
目录下创建META-INF\spring.factories
文件,将自动配置类添加到文件中,应用程序启动时,会利用SPI 机制将这个类加载到容器中,就不需要配置包扫描了。
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.pearl.minio.autoconfigure.MinioAutoConfiguration
首先使用 mvn install
将该自定义Starter 项目安装到本地仓库。
在Spring Boot 业务项目中,引入依赖:
<dependency>
<groupId>com.pearlgroupId>
<artifactId>pearl-minio-spring-boot-starterartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
添加Minio 客户端的配置:
pearl:
minio:
enabled: true
endpoint: http://127.0.0.1:9000
access-key: admin
secret-key: admin123
可以看到添加的时候,是由提示功能的非常方便:
然后直接在业务代码中,注入MinioClient
并执行功能:
@RestController
@RequestMapping("/minio")
public class MinioController {
@Autowired
MinioClient minioClient;
@GetMapping("/test")
public Object test() throws Exception {
// 调用Minio 客户端查询存储桶是否存在
return minioClient.bucketExists(BucketExistsArgs.builder().bucket("bucket").build());
}
}
测试发现,没法问题,一个简单的自定义Starter 包就完成了,在实际开发中,我们可以将很多第三方库封装为Starter 组件,上传到公司私服库中,业务开发时,需要某个功能,主要引入组件即可,不用自己再配置什么的了,非常的方便也很有必要这么做~