Spring Boot 封装 MinIO 工具类完整指南

📅 2025-12-19 17:18:25 阅读时间: 24分钟

本文详细介绍了如何在 Spring Boot 项目中封装 MinIO 对象存储工具类,提供完整的配置和工具方法。

MinIO 简介

MinIO 是一款高性能、开源、兼容 Amazon S3 API 的分布式对象存储系统,专为云原生架构和大规模非结构化数据场景设计。其核心定位是成为私有云/混合云环境中的标准存储方案,适用于从数据湖到 AI/ML、容器化部署等多样化需求。

项目结构

复制代码
cdkj-minio
├── annotation                    # 注解
│   └── EnableAutoMinio          # 启用自动 MinIO 配置
├── config                        # 配置类
│   ├── MinioAutoConfiguration   # MinIO 自动配置
│   ├── MinioMarkerConfiguration # MinIO 标记配置
│   └── MinioProperties          # MinIO 配置读取
├── connectivity                  # 连接库
│   └── MinioConfiguration       # MinIO 连接配置
├── enums                         # 枚举库
│   └── ContentTypeEnums         # 内容类型枚举
└── MinioUtils                   # MinIO 工具类核心

快速开始

1. POM 依赖配置

xml 复制代码
<dependencies>
    <!-- MinIO -->
    <dependency>
        <groupId>io.minio</groupId>
        <artifactId>minio</artifactId>
        <exclusions>
            <exclusion>
                <groupId>com.squareup.okhttp3</groupId>
                <artifactId>okhttp</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>com.squareup.okhttp3</groupId>
        <artifactId>okhttp</artifactId>
    </dependency>
</dependencies>

2. 启用自动配置

EnableAutoMinio 注解:

java 复制代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({MinioMarkerConfiguration.class})
public @interface EnableAutoMinio {}

Spring Boot 项目引入:

java 复制代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@EnableRetry
@EnableAsync
@Configuration
@EnableAutoMinio
@EnableAutoMongo
@EnableAutoCdkjJob
@EnableDiscoveryClient
@EnableTransactionManagement
@EnableFeignClients(basePackages = {"com.*.*.client"})
public @interface EnableAutoApi {}

3. 配置文件

MinioProperties 配置类:

java 复制代码
@Data
@RefreshScope
@Configuration
@ConfigurationProperties(prefix = "spring.minio")
public class MinioProperties {
    private String domain;        // 访问域名
    private String endpoint;     // 存储端点
    private Integer port;        // 端口
    private String accessKey;    // 访问密钥
    private String secretKey;    // 密钥
    private String bucketName;   // 存储桶名称
    private Integer expiry;      // 分片对象过期时间(天)
    private Integer breakpointTime; // 断点续传有效时间(天)
}

4. 内容类型枚举

java 复制代码
public enum ContentTypeEnums {
    DEFAULT("default", "application/octet-stream"),
    JPG("jpg", "image/jpeg"),
    PNG("png", "image/png"),
    MP4("mp4", "video/mp4");
    // ... 更多类型
    
    public static String formContentType(String suffix) {
        // 根据文件后缀获取 Content-Type
    }
}

核心工具类功能

1. 文件上传

普通文件上传:

java 复制代码
public static ObjectWriteResponse uploadFile(String bucketName, 
                                           MultipartFile file, 
                                           String fileName, 
                                           ContentTypeEnums contentType) throws Exception {
    InputStream inputStream = file.getInputStream();
    return client.putObject(PutObjectArgs.builder()
            .bucket(bucketName)
            .object(fileName)
            .contentType(contentType.getValue())
            .stream(inputStream, inputStream.available(), -1)
            .build());
}

分片上传:

java 复制代码
public static ResponseBuilder uploadFileFragment(MultipartFile file, 
                                                Integer currIndex, 
                                                Integer totalPieces, 
                                                String md5) throws Exception {
    // 分片上传实现,支持大文件断点续传
}

2. 文件管理

文件存在性检查:

java 复制代码
public static boolean isFileExist(String bucketName, String fileName) {
    try {
        client.statObject(StatObjectArgs.builder()
                .bucket(bucketName)
                .object(fileName)
                .build());
        return true;
    } catch (Exception e) {
        return false;
    }
}

文件列表获取:

java 复制代码
public static Iterable<Result<Item>> getFilesByPrefix(String bucketName, 
                                                     String prefix, 
                                                     boolean recursive) {
    return client.listObjects(ListObjectsArgs.builder()
            .bucket(bucketName)
            .prefix(prefix)
            .recursive(recursive)
            .build());
}

3. 文件下载

获取文件流:

java 复制代码
public InputStream getFileStream(String bucketName, String fileName) throws Exception {
    return client.getObject(GetObjectArgs.builder()
            .bucket(bucketName)
            .object(fileName)
            .build());
}

断点下载:

java 复制代码
public InputStream getFileStream(String bucketName, String fileName, 
                               long offset, long length) throws Exception {
    return client.getObject(GetObjectArgs.builder()
            .bucket(bucketName)
            .object(fileName)
            .offset(offset)
            .length(length)
            .build());
}

4. 文件删除

批量删除:

java 复制代码
public static Iterable<Result<DeleteError>> removeFiles(String bucketName, 
                                                       List<String> filePaths) {
    List<DeleteObject> objectPaths = filePaths.stream()
            .map(DeleteObject::new)
            .collect(Collectors.toList());
    return client.removeObjects(RemoveObjectsArgs.builder()
            .bucket(bucketName)
            .objects(objectPaths)
            .build());
}

5. 预签名 URL

生成临时访问链接:

java 复制代码
public static String getPresignedObjectUrl(String bucketName, String fileName) throws Exception {
    GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
            .bucket(bucketName)
            .object(fileName)
            .method(Method.GET)
            .build();
    return client.getPresignedObjectUrl(args);
}

自动配置原理

配置标记类

java 复制代码
@Configuration(proxyBeanMethods = false)
public class MinioMarkerConfiguration {
    @Bean
    public Marker mybatisMarker() {
        return new Marker();
    }
    public static class Marker {}
}

自动配置类

java 复制代码
@Lazy(false)
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties({MinioProperties.class})
@AutoConfigureAfter({WebClientAutoConfiguration.class})
@ConditionalOnBean(MinioMarkerConfiguration.Marker.class)
public class MinioAutoConfiguration {
    
    @Bean(initMethod = "start")
    public MinioConfiguration minioConfiguration() {
        return new MinioConfiguration(minioProperties);
    }
}

连接配置

java 复制代码
public class MinioConfiguration {
    public void start() {
        MinioClient.Builder builder = MinioClient.builder();
        if (minioProperties.getPort() == null) {
            builder.endpoint(minioProperties.getEndpoint());
        } else {
            builder.endpoint(minioProperties.getEndpoint(), 
                           minioProperties.getPort(), false);
        }
        
        MinioClient client = builder
                .credentials(minioProperties.getAccessKey(), 
                           minioProperties.getSecretKey())
                .build();
                
        new MinioUtils(client); // 实例化工具类
    }
}

Spring Boot 3.x 支持

resources/META-INF/spring 目录下创建 org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件:

复制代码
com.cdkjframework.minio.config.MinioAutoConfiguration

总结

Spring Boot 封装 MinIO 工具的核心意义在于将分布式存储能力转化为可复用的基础设施,通过标准化、模块化的设计,显著降低开发复杂度,提升系统健壮性和可维护性。这种封装不仅是技术层面的优化,更是工程实践中的最佳选择,尤其适用于需要快速迭代、高并发处理及多云兼容的现代应用架构。

主要特性:

  • 开箱即用的自动配置
  • 完整的分片上传支持
  • 灵活的预签名 URL 生成
  • 完善的异常处理机制
  • 与 Spring Boot 生态无缝集成

开源地址:

如果觉得项目对你有帮助,欢迎 Star 和 Fork!如有问题或建议,欢迎留言讨论。