自定义一个springboot starter
1.自定义starter的作用
在我们的日常开发工作中,经常会有一些独立于业务之外的配置模块,比如阿里云oss存储的时候,我们需要一个工具类进行文件上传。我们经常将其放到一个特定的包下,然后如果另一个工程需要复用这块功能的时候,需要将代码硬拷贝到另一个工程,重新集成一遍,这样会非常麻烦。如果我们将这些可独立于业务代码之外的功配置模块封装成一个个starter,复用的时候只需要在 maven pom 中引用依赖即可,让 SpringBoot 为我们完成自动装配,提高开发效率。
2.自定义starter命名规范
SpringBoot提供的 starter 以 spring-boot-starter-xxx 的方式命名的。官方建议自定义的 starter 使用 xxx-spring-boot-starter 命名规则。以区分 SpringBoot 生态提供的 starter。如:mybatis-spring-boot-starter
3.自定义starter的步骤
现在就以自定义阿里云oss工具starter为例步骤如下:
- 新建两个maven模块
(1)aliyun-oss-spring-boot-autoconfigure:自动配置核心代码
(2)aliyun-oss-spring-boot-starter:管理依赖
-
在aliyun-oss-spring-boot-autoconfigure的pom文件中引入以下依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.15.1</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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> </dependencies>
-
在aliyun-oss-spring-boot-autoconfigure的java里面的对应的包里新建三个文件
AliOSSProperties.java
package com.minqiliang; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties("aliyun.oss") public class AliOSSProperties { private String endpoint; private String accessKeyId; private String accessKeySecret; private String bucketName; /** * 获取 * @return endpoint */ public String getEndpoint() { return endpoint; } /** * 设置 * @param endpoint */ public void setEndpoint(String endpoint) { this.endpoint = endpoint; } /** * 获取 * @return accessKeyId */ public String getAccessKeyId() { return accessKeyId; } /** * 设置 * @param accessKeyId */ public void setAccessKeyId(String accessKeyId) { this.accessKeyId = accessKeyId; } /** * 获取 * @return accessKeySecret */ public String getAccessKeySecret() { return accessKeySecret; } /** * 设置 * @param accessKeySecret */ public void setAccessKeySecret(String accessKeySecret) { this.accessKeySecret = accessKeySecret; } /** * 获取 * @return bucketName */ public String getBucketName() { return bucketName; } /** * 设置 * @param bucketName */ public void setBucketName(String bucketName) { this.bucketName = bucketName; } }
AliOSSUtils.java
package com.minqiliang; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.io.InputStream; import java.util.UUID; /** * 阿里云 OSS 工具类 */ public class AliOSSUtils { private AliOSSProperties aliOSSProperties; public AliOSSProperties getAliOSSProperties() { return aliOSSProperties; } public void setAliOSSProperties(AliOSSProperties aliOSSProperties) { this.aliOSSProperties = aliOSSProperties; } /** * 实现上传图片到OSS */ public String upload(MultipartFile file) throws IOException { String endpoint = aliOSSProperties.getEndpoint(); String accessKeyId = aliOSSProperties.getAccessKeyId(); String accessKeySecret = aliOSSProperties.getAccessKeySecret(); String bucketName = aliOSSProperties.getBucketName(); // 获取上传的文件的输入流 InputStream inputStream = file.getInputStream(); // 避免文件覆盖 String originalFilename = file.getOriginalFilename(); String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf(".")); //上传文件到 OSS OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); ossClient.putObject(bucketName, fileName, inputStream); //文件访问路径 String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName; // 关闭ossClient ossClient.shutdown(); return url;// 把上传到oss的路径返回 } }
AliyunOssAutoConfigration.java
package com.minqiliang; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @EnableConfigurationProperties(AliOSSProperties.class) public class AliyunOssAutoConfigration { @Bean public AliOSSUtils aliOSSUtils(AliOSSProperties aliOSSProperties){ AliOSSUtils aliossUtils = new AliOSSUtils(); aliossUtils.setAliOSSProperties(aliOSSProperties); return aliossUtils; } }
-
aliyun-oss-spring-boot-autoconfigure的resources文件加下新建META_INF/spring文件夹,然后再在spring文件夹里新建org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,文件内容为AliyunOssAutoConfigration类的全类名,如下
com.minqiliang.AliyunOssAutoConfigration
-
在aliyun-oss-spring-boot-starter的pom文件里引入aliyun-oss-spring-boot-autoconfigure依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>com.minqiliang</groupId> <artifactId>aliyun-oss-spring-boot-autoconfigure</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies>
-
目录结构如下
-
执行clean和install,把自定义的starter安装到本地仓库
-
新建一个aliyun-starter-test模块,进行测试,目录结构如下:
-
UploadController.java
package com.example.controller; import com.example.pojo.Result; import com.minqiliang.AliOSSUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; @RestController public class UploadController { @Autowired private AliOSSUtils aliOSSUtils; @PostMapping("upload") public Result upload(MultipartFile image) throws IOException { String url = aliOSSUtils.upload(image); return Result.success(url); } }
Result.java
package com.example.pojo; public class Result { private Integer code;//响应码,1 代表成功; 0 代表失败 private String msg; //响应信息 描述字符串 private Object data; //返回的数据 public Result() { } public Result(Integer code, String msg, Object data) { this.code = code; this.msg = msg; this.data = data; } //增删改 成功响应 public static Result success(){ return new Result(1,"success",null); } //查询 成功响应 public static Result success(Object data){ return new Result(1,"success",data); } //失败响应 public static Result error(String msg){ return new Result(0,msg,null); } /** * 获取 * @return code */ public Integer getCode() { return code; } /** * 设置 * @param code */ public void setCode(Integer code) { this.code = code; } /** * 获取 * @return msg */ public String getMsg() { return msg; } /** * 设置 * @param msg */ public void setMsg(String msg) { this.msg = msg; } /** * 获取 * @return data */ public Object getData() { return data; } /** * 设置 * @param data */ public void setData(Object data) { this.data = data; } public String toString() { return "Result{code = " + code + ", msg = " + msg + ", data = " + data + "}"; } }
-
pom文件引入aliyun-oss-spring-boot-starter依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.minqiliang</groupId> <artifactId>aliyun-oss-spring-boot-starter</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies>
-
application.yml里配置自己的阿里云oss信息,如下
aliyun: oss: endpoint: 填写自己的 accessKeyId: 填写自己的 accessKeySecret: 填写自己的 bucketName: 填写自己的
-
启动测试项目,使用postman上传一个文件,结果如下,说明starter配置成功
{ "code": 1, "msg": "success", "data": "https://tlias-manage.oss-cn-hangzhou.aliyuncs.com/8713ed3d-751c-4d54-8a64-239b1ccb0da4.jpg" }