SpringBootzhong自定义starter

143 阅读3分钟

自定义starter是SpringBoot将功能封装成可复用组件的方式,可以让其他的项目简单的进入依赖,即可快速使用该功能,无需重复配置可以减少许多配置.既然自定义strarter可以减少配置,那么先来讲怎么实现自定义starter.

一、自定义 Starter的实现

命名规范:

一. 官方Starter和自定义Starter有所不同,是为了防止出现自定义的和官方的出现冲突.

  • 官方:spring-boot-autoconfigure-xxx(如spring-boot-autoconfigure-web
  • 自定义:xxx-spring-boot-autoconfigure(如log-spring-boot-autoconfigure

image.png

二. 在自定义的模块下的xxx-spring-boot-autoconfigure的实现
  1. pom.xml文件中添加Spring Boot自动配置的核心依赖:
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.0.2</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>


  <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-autoconfigure</artifactId>
        <version>3.0.2</version> <!-- 需与目标项目Spring Boot版本匹配,也可以省略 -->
    </dependency

image.png

  1. 定义配置属性类
  • 定义一个xxxProperties,用于接收外部配置,如:
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliyunOSSProperties {
    private String endpoint;
    private String bucketName;
    private String region;
  1. 定义核心功能类(需要实现的功能),格式:xxxAutoConfiguration,如阿里云OSS上传文件实现类
public class AliyunOSSOperator {
    private AliyunOSSProperties aliyunOSSProperties;
    public AliyunOSSOperator(AliyunOSSProperties aliyunOSSProperties) {
        this.aliyunOSSProperties = aliyunOSSProperties;
    }
    public void deleteByUrls(List<String> keys) throws Exception {
        //log.info("old keys:{}", keys);
        String endpoint = aliyunOSSProperties.getEndpoint();
        String bucketName = aliyunOSSProperties.getBucketName();
        String region = aliyunOSSProperties.getRegion();

        String urlPrefix = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/";
        keys = keys.stream()
                .map(item -> item.replaceAll(urlPrefix, ""))
                .toList();
       // log.info("new keys:{}", keys);
        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();

        // 创建OSSClient实例。
        // 当OSSClient实例不再使用时,调用shutdown方法以释放资源。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        try {
            //批量删除OSS文件
            DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(keys).withEncodingType("url"));
            List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
            for(String obj : deletedObjects) {
                String deleteObj =  URLDecoder.decode(obj, "UTF-8");
                System.out.println(deleteObj);
            }
        } catch (Exception oe) {
            System.out.println(oe.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    public String upload(byte[] content, String originalFilename) throws Exception {

        String endpoint = aliyunOSSProperties.getEndpoint();
        String bucketName = aliyunOSSProperties.getBucketName();
        String region = aliyunOSSProperties.getRegion();

        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();

        // 填写Object完整路径,例如202406/1.png。Object完整路径中不能包含Bucket名称。
        //获取当前系统日期的字符串,格式为 yyyy/MM
        String dir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM"));
        //生成一个新的不重复的文件名
        String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
        String objectName = dir + "/" + newFileName;

        // 创建OSSClient实例。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        try {
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content));
        } catch (Exception oe) {
            System.out.println(oe.getMessage());
        } finally{
            ossClient.shutdown();
        }

        return endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + objectName;
    }

}
  1. 编写自动配置类(用于完成bean的创建和注入),格式:xxAutoConfiguration 类
@EnableConfigurationProperties({AliyunOSSProperties.class})     
public class AliyunOssAutoConfiguration {

    @Bean
    public AliyunOSSOperator aliyunOSSOperator(AliyunOSSProperties aliyunOSSProperties) {
        return new AliyunOSSOperator(aliyunOSSProperties);
    }
}
  1. 通过Spring自动化装配原理完成 XxxAutoConfiguration 类的初始化操作
  • src/main/resources/META-INF/目录下创建additional-spring-configuration-metadata.json文件
  • 在文件中写入XxxAutoConfiguration 的全类名

三.xxx-spring-boot-start模块下实现

  1. pom.xml文件中添加Spring Boot自动配置的核心依赖:
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.0.2</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

2.在xml文件中添加,xxx-spring-boot-autoconfigure的依赖

<dependencies>
    <dependency>
        <groupId>com.itheima</groupId>
        <artifactId>aliyun-oss-spring-boot-autoconfigure</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

image.png

image.png

  • xxx-spring-boot-start模块只负责管理依赖(导入下面的xxx-spring-boot-autoconfigure的依赖),不实现功能

四. 打包发布和使用

1.打包发布

  • 用黑窗口执行mvn clean install将 Starter 安装到本地仓库(或发布到私服),供其他项目依赖。
  • 或用IDE打包发布
  1. 使用
  • 在其他Spring Boot项目中进入该依赖,在pom.xml中引入,如
<dependency>
    <groupId>com.itheima</groupId>
    <artifactId>aliyun-oss-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

image.png

  1. 使用功能 直接注入即可使用