自定义 starter - SpringBoot 的起步依赖
自定义 starter
所谓 starter 指的就是 SpringBoot 当中的起步依赖。在 SpringBoot 当中已经给我们提供了很多的起步依赖了,我们为什么还需要自定义 starter 起步依赖?
这是因为在实际的项目开发当中,我们可能会用到很多第三方的技术,并不是所有的第三方的技术官方都给我们提供了与 SpringBoot 整合的 starter 起步依赖,但是这些技术又非常的通用,在很多项目组当中都在使用。
这里使用阿里云 OSS 文件上传举例。
1. 分析
首先先了解官方、第三方提供的起步依赖的框架是怎么设计的。
在 Springboot 中,官方提供的起步依赖 或 第三方提供的起步依赖,基本都会包含两个模块,如下所示:

其中,spring-boot-starter 或 xxx-spring-boot-starter 这个模块主要是依赖管理的功能。 而 spring-boot-autoconfigure 或 xxxx-spring-boot-autoconfigure 主要是起到自动配置的作用,自动配置的核心代码就在这个模块中编写。
SpringBoot 官方 starter 命名:spring-boot-starter-xxxx
第三组织提供的 starter 命名:xxxx-spring-boot-starter
而自动配置模块的核心,就是编写自动配置的核心代码,然后将自动配置的核心类,配置在核心的配置文件 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 中。
SpringBoot 项目启动时,会读取到
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports配置文件中的配置类并加载配置类,生成相关 bean 对象注册到 IOC 容器中。结论:我们可以直接在 SpringBoot 程序中使用自动配置的 bean 对象。
2. 实现
2.1 依赖管理
定义 aliyun-oss-spring-boot-start 模块,把阿里云 OSS 所有的依赖统一管理起来,创建完后的项目只需要保留 pom.xml 文件即可

配置如下:
<?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.aliyun.oss</groupId>
<artifactId>aliyun-oss-spring-boot-start</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>3.0.2</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-oss-spring-boot-autoconfigure</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
2.2 启动依赖
创建 autoconfigure 模块 aliyun-oss-spring-boot-autoconfigure 配置启动依赖

修改配置依赖 pom.xml:
<?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.aliyun.oss</groupId>
<artifactId>aliyun-oss-spring-boot-autoconfigure</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.17.4</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
</dependency>
<!-- hutool:专门用来做工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.27</version>
</dependency>
</dependencies>
</project>
2.3 搭建
将有关于文件上传的代码放入启动依赖中:
// 参数配置类
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliyunOssProperties {
private String domain;
private String endpoint;
private String bucketName;
private String region;
private String accessKeyId;
private String secretAccessKey;
// 注意:手动生成 Getter、Setter 方法,不推荐使用 lombok
}
// 阿里云文件上传工具类
public class AliyunOssUtils {
private final AliyunOssProperties aliyunOssProperties;
public AliyunOssUtils(AliyunOssProperties aliyunOssProperties) {
this.aliyunOssProperties = aliyunOssProperties;
}
/**
* 上传文件
*
* @return: String 上传后文件的路径
* @param: file 文件
*/
public String uploadFile(MultipartFile file) {
// 参数校验
if (ObjUtil.isEmpty(file) || file.isEmpty()) {
throw new RuntimeException("上传文件不能为空");
}
String filename = file.getOriginalFilename();
if (StrUtil.isEmpty(filename)) {
throw new RuntimeException("上传文件名错误!");
}
// 上传后的文件路径
String path = null;
OSS ossClient = null;
try {
// 参数设置
// 单独保存域名,方便后续拼接文件名
String domain = aliyunOssProperties.getDomain();
// 设置 OSS Endpoint 和 Bucket 名称
String endpoint = aliyunOssProperties.getEndpoint();
String bucketName = aliyunOssProperties.getBucketName();
// 替换为您的 Bucket 区域
String region = aliyunOssProperties.getRegion();
// 创建 OSSClient 实例
String accessKeyId = aliyunOssProperties.getAccessKeyId();
String secretAccessKey = aliyunOssProperties.getSecretAccessKey();
// 自定义配置阿里云账号
CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, secretAccessKey);
// 创建 OSSClient 实例
ossClient = OSSClientBuilder.create().endpoint(endpoint).credentialsProvider(credentialsProvider).credentialsProvider(credentialsProvider).region(region).build();
// String.lastIndexOf() 方法返回指定字符串中最后一次出现的指定字符的索引位置,如果没有找到则返回 -1。
// 获取文件名后缀(即文件类型),如:.jpg
String suffix = filename.substring(filename.lastIndexOf("."));
// 生成随机文件名,并拼接文件类型
filename = UUID.randomUUID().toString().replaceAll("-", "") + suffix;
// 上传文件到阿里云
ossClient.putObject(bucketName, filename, file.getInputStream());
// 拼接文件路径
path = "https://" + bucketName + "." + domain + "/" + filename;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
return path;
}
}
// 阿里云OSS自动配置类
@Configuration
@ConditionalOnClass(OSS.class)
@EnableConfigurationProperties(AliyunOssProperties.class)
public class AliOssAutoConfiguration {
@Bean
public AliyunOssUtils aliyunOssUtils(AliyunOssProperties aliyunOssProperties) {
return new AliyunOssUtils(aliyunOssProperties);
}
}
2.4 配置指定装配(重点)
在 src/main/resources 文件下新建 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件

只需要将自动配置类的全类名配置到 org.springframework.boot.autoconfigure.AutoConfiguration.imports 中即可
com.aliyun.oss.autoconfigure.AliOssAutoConfiguration
3. 使用自定义 starter
最终搭建完成的 starter 的项目结构应为:

3.1 引入依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-oss-spring-boot-start</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
3.2 配置
在 application.yml 配置文件中自行配置自己的阿里云 OSS 信息
# 自定义参数
aliyun:
oss:
# 单独保存域名,方便使用
domain: oss-cn-**.aliyuncs.com
# 设置 OSS Endpoint 和 Bucket 名称
endpoint: https://oss-cn-**.aliyuncs.com
bucketName: ***
# 替换为您的 Bucket 区域
region: cn-beijing # 这里以北京举例
# 创建 OSSClient 实例
accessKeyId: YOUR-ACCESS-KEY-ID
secretAccessKey: YOUR-SECRET-ACCESS-KEY
3.3 正常使用即可
// 文件管理控制器
@RestController
@RequiredArgsConstructor
public class FileController {
private final AliyunOssUtils aliyunOssUtils;
@PostMapping("/upload")
public Result uploadImg(@RequestParam("file") MultipartFile file) {
String s = aliyunOssUtils.uploadFile(file);
return Result.success(s);
}
}

浙公网安备 33010602011771号