文章目录
- 1.minio安装
- 1.拉取镜像
- 2.启动容器
- 3.开启端口
- 1.9090端口
- 2.9000端口
- 4.访问
- 1.网址http://:9090/
- 5.创建一个桶
- 2.minio文件服务基本环境搭建
- 1.创建一个文件模块
- 2.目录结构
- 3.配置依赖
- 3.application.yml 配置
- 4.编写配置类MinioConfig.java,构建minioClient
- 5.FileInfo.java 封装文件信息
- 6.MinioUtil.java 文件工具类
- 7.FileController.java 测试
- 8.启动类 OssApplication.java
- 9.启动测试
- 3.传统模式
- 1.目录结构和类图
- 2.首先引入Lombok的依赖,使用@SneakyThrows注解抛出异常
- 3.StorageService.java 存储的接口
- 4.MinioStorageServiceImpl.java minio实现的接口
- 5.如果有其他的服务比如阿里云也可以实现接口
- 6.FileController.java 按照id来依赖注入进行调用
- 7.测试
- 8.缺点分析
- 4.使用适配器模式优化
- 1.类图
- 2.新增一个阿里云的实现类 AliyunStorageServiceImpl.java
- 3.抽取一个 FileService.java 构造器聚合接口
- 4.StorageConfig.java 配置文件根据application.yml来给构造器注入不同的对象
- 5.application.yml 指定要使用的oss
- 6.FileController.java 组合一个FileService调用里面的方法
- 7.测试
1.minio安装
1.拉取镜像
docker pull minio/minio
2.启动容器
docker run -p 9000:9000 -p 9090:9090 \--name minio \-d --restart=always \-e "MINIO_ACCESS_KEY=" \-e "MINIO_SECRET_KEY=" \-v /mydata/minio/data:/data \minio/minio server \/data --console-address ":9090" -address ":9000"
3.开启端口
1.9090端口
systemctl start firewalld && firewall-cmd --permanent --add-port=9090/tcp && firewall-cmd --reload && firewall-cmd --query-port=9090/tcp
2.9000端口
systemctl start firewalld && firewall-cmd --permanent --add-port=9000/tcp && firewall-cmd --reload && firewall-cmd --query-port=9000/tcp
4.访问
1.网址http://:9090/
5.创建一个桶
2.minio文件服务基本环境搭建
1.创建一个文件模块
2.目录结构
3.配置依赖
<!-- maven的配置 -->
<!-- 解决java: -source 1.5 中不支持 diamond 运算符 问题 -->
<properties><java.version>1.8</java.version><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target>
</properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.4.2</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.4.2</version><exclusions><exclusion><artifactId>spring-boot-starter-logging</artifactId><groupId>org.springframework.boot</groupId></exclusion></exclusions></dependency><!-- minio依赖 --><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.2.0</version></dependency>
</dependencies><!-- 配置阿里云仓库 -->
<repositories><repository><id>central</id><name>aliyun maven</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url><layout>default</layout><releases><enabled>true</enabled></releases><snapshots><enabled>true</enabled></snapshots></repository>
</repositories><!-- maven打包常规配置 -->
<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>
3.application.yml 配置
server:port: 4000
minio:url: http://:9000accessKey: secretKey:
4.编写配置类MinioConfig.java,构建minioClient
package com.sunxiansheng.oss.config;import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** Description: minio配置管理* @Author sun* @Create 2024/5/31 9:22* @Version 1.0*/
@Configuration
public class MinioConfig {// minioUrl@Value("${minio.url}")private String url;// minio用户名@Value("${minio.accessKey}")private String accessKey;// minio密码@Value("${minio.secretKey}")private String secretKey;/*** 构造minioClient*/@Beanpublic MinioClient getMinioClient() {return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();}}
5.FileInfo.java 封装文件信息
package com.sunxiansheng.oss.entity;/*** Description:* @Author sun* @Create 2024/5/31 9:47* @Version 1.0*/
public class FileInfo {private String fileName;private Boolean directoryFlag;private String etag;public String getFileName() {return fileName;}public void setFileName(String fileName) {this.fileName = fileName;}public Boolean getDirectoryFlag() {return directoryFlag;}public void setDirectoryFlag(Boolean directoryFlag) {this.directoryFlag = directoryFlag;}public String getEtag() {return etag;}public void setEtag(String etag) {this.etag = etag;}
}
6.MinioUtil.java 文件工具类
package com.sunxiansheng.oss.util;import com.sunxiansheng.oss.entity.FileInfo;
import io.minio.*;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;/*** Description: minio文件操作工具* @Author sun* @Create 2024/5/31 9:30* @Version 1.0*/
@Component
public class MinioUtil {@Resourceprivate MinioClient minioClient;/*** 创建bucket桶*/public void createBucket(String bucket) throws Exception {boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());if (!exists) {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());}}/*** 上传文件*/public void uploadFile(InputStream inputStream, String bucket, String objectName) throws Exception {minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(objectName).stream(inputStream, -1, Integer.MAX_VALUE).build());}/*** 列出所有桶*/public List<String> getAllBucket() throws Exception {List<Bucket> buckets = minioClient.listBuckets();return buckets.stream().map(Bucket::name).collect(Collectors.toList());}/*** 列出当前桶及文件*/public List<FileInfo> getAllFile(String bucket) throws Exception {Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucket).build());List<FileInfo> fileInfoList = new LinkedList<>();for (Result<Item> result : results) {FileInfo fileInfo = new FileInfo();Item item = result.get();fileInfo.setFileName(item.objectName());fileInfo.setDirectoryFlag(item.isDir());fileInfo.setEtag(item.etag());fileInfoList.add(fileInfo);}return fileInfoList;}/*** 下载文件*/public InputStream downLoad(String bucket, String objectName) throws Exception {return minioClient.getObject(GetObjectArgs.builder().bucket(bucket).object(objectName).build());}/*** 删除桶*/public void deleteBucket(String bucket) throws Exception {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucket).build());}/*** 删除文件*/public void deleteObject(String bucket, String objectName) throws Exception {minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectName).build());}}
7.FileController.java 测试
package com.sunxiansheng.oss.controller;import com.sunxiansheng.oss.util.MinioUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import java.util.List;/*** Description:* @Author sun* @Create 2024/5/31 9:53* @Version 1.0*/
@RestController
public class FileController {@Resourceprivate MinioUtil minioUtil;@RequestMapping("/testGetAllBuckets")public String testGetAllBuckets() throws Exception {List<String> allBucket = minioUtil.getAllBucket();return allBucket.get(0);}}
8.启动类 OssApplication.java
package com.sunxiansheng.oss;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;/*** Description:* @Author sun* @Create 2024/5/31 9:20* @Version 1.0*/
@SpringBootApplication
@ComponentScan("com.sunxiansheng")
public class OssApplication {public static void main(String[] args) {SpringApplication.run(OssApplication.class, args);}
}
9.启动测试
3.传统模式
1.目录结构和类图
2.首先引入Lombok的依赖,使用@SneakyThrows注解抛出异常
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.16</version></dependency>
3.StorageService.java 存储的接口
package com.sunxiansheng.oss.service;import com.sunxiansheng.oss.entity.FileInfo;
import org.springframework.web.multipart.MultipartFile;import java.io.InputStream;
import java.util.List;/*** Description:* @Author sun* @Create 2024/5/31 10:03* @Version 1.0*/
public interface StorageService {/*** 创建bucket桶*/void createBucket(String bucket);/*** 上传文件*/void uploadFile(MultipartFile uploadFile, String bucket, String objectName);/*** 列出所有桶*/List<String> getAllBucket();/*** 列出当前桶及文件*/List<FileInfo> getAllFile(String bucket);/*** 下载文件*/InputStream downLoad(String bucket, String objectName);/*** 删除桶*/void deleteBucket(String bucket);/*** 删除文件*/void deleteObject(String bucket, String objectName);}
4.MinioStorageServiceImpl.java minio实现的接口
package com.sunxiansheng.oss.service.impl;import com.sunxiansheng.oss.entity.FileInfo;
import com.sunxiansheng.oss.service.StorageService;
import com.sunxiansheng.oss.util.MinioUtil;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import java.io.InputStream;
import java.util.List;/*** Description:* @Author sun* @Create 2024/5/31 10:06* @Version 1.0*/
@Service("minioStorageServiceImpl")
public class MinioStorageServiceImpl implements StorageService {@Resourceprivate MinioUtil minioUtil;@Override@SneakyThrows // Lombok 自动抛出异常public void createBucket(String bucket) {minioUtil.createBucket(bucket);}@Override@SneakyThrows // Lombok 自动抛出异常public void uploadFile(MultipartFile uploadFile, String bucket, String objectName) {createBucket(bucket);if (objectName != null) {minioUtil.uploadFile(uploadFile.getInputStream(), bucket, objectName + "/" + uploadFile.getName());} else {minioUtil.uploadFile(uploadFile.getInputStream(), bucket, uploadFile.getName());}}@Override@SneakyThrows // Lombok 自动抛出异常public List<String> getAllBucket() {return minioUtil.getAllBucket();}@Override@SneakyThrows // Lombok 自动抛出异常public List<FileInfo> getAllFile(String bucket) {return minioUtil.getAllFile(bucket);}@Override@SneakyThrows // Lombok 自动抛出异常public InputStream downLoad(String bucket, String objectName) {return minioUtil.downLoad(bucket, objectName);}@Override@SneakyThrows // Lombok 自动抛出异常public void deleteBucket(String bucket) {minioUtil.deleteBucket(bucket);}@Override@SneakyThrows // Lombok 自动抛出异常public void deleteObject(String bucket, String objectName) {minioUtil.deleteObject(bucket, objectName);}
}
5.如果有其他的服务比如阿里云也可以实现接口
6.FileController.java 按照id来依赖注入进行调用
package com.sunxiansheng.oss.controller;import com.sunxiansheng.oss.service.StorageService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import java.util.List;/*** Description:* @Author sun* @Create 2024/5/31 9:53* @Version 1.0*/
@RestController
public class FileController {// 这里根据id进行依赖注入,如果还有阿里云的,就注入阿里云的即可@Resourceprivate StorageService minioStorageServiceImpl;@RequestMapping("/listBuckets")public String testGetAllBuckets() throws Exception {List<String> allBucket = minioStorageServiceImpl.getAllBucket();return allBucket.get(0);}}
7.测试
8.缺点分析
如果需要修改为阿里云的,则需要修改注入的id,也就是所有的controller都需要修改
4.使用适配器模式优化
1.类图
2.新增一个阿里云的实现类 AliyunStorageServiceImpl.java
package com.sunxiansheng.oss.service.impl;import com.sunxiansheng.oss.entity.FileInfo;
import com.sunxiansheng.oss.service.StorageService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;/*** Description:* @Author sun* @Create 2024/5/31 11:13* @Version 1.0*/
@Service("aliyunStorageServiceImpl")
public class AliyunStorageServiceImpl implements StorageService {@Overridepublic void createBucket(String bucket) {}@Overridepublic void uploadFile(MultipartFile uploadFile, String bucket, String objectName) {}@Overridepublic List<String> getAllBucket() {List<String> res = new ArrayList<>();res.add("aliyunBucket");return res;}@Overridepublic List<FileInfo> getAllFile(String bucket) {return Collections.emptyList();}@Overridepublic InputStream downLoad(String bucket, String objectName) {return null;}@Overridepublic void deleteBucket(String bucket) {}@Overridepublic void deleteObject(String bucket, String objectName) {}
}
3.抽取一个 FileService.java 构造器聚合接口
package com.sunxiansheng.oss.service;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;/*** Description:* @Author sun* @Create 2024/5/31 10:48* @Version 1.0*/
@Service
public class FileService {private final StorageService storageService;@Autowired // 构造器注入,如果只有一个构造器,其实可以不加,会自动识别public FileService(StorageService storageService) {this.storageService = storageService;}/*** 列出所有桶*/public List<String> getAllBucket() {return storageService.getAllBucket();}}
4.StorageConfig.java 配置文件根据application.yml来给构造器注入不同的对象
package com.sunxiansheng.oss.config;import com.sunxiansheng.oss.service.StorageService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.annotation.Resource;/*** Description:* @Author sun* @Create 2024/5/31 11:10* @Version 1.0*/
@Configuration
public class StorageConfig {@Value("${storage.service.type}")private String storageType;@Resourceprivate StorageService aliyunStorageServiceImpl;@Resourceprivate StorageService minioStorageServiceImpl;@Beanpublic StorageService storageService() {if ("minio".equals(storageType)) {return minioStorageServiceImpl;} else if ("aliyun".equals(storageType)) {return aliyunStorageServiceImpl;} else {throw new IllegalArgumentException("未找到对应的文件存储处理");}}}
5.application.yml 指定要使用的oss
6.FileController.java 组合一个FileService调用里面的方法
package com.sunxiansheng.oss.controller;import com.sunxiansheng.oss.service.FileService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import java.util.List;/*** Description:* @Author sun* @Create 2024/5/31 9:53* @Version 1.0*/
@RestController
public class FileController {// 这里根据id进行依赖注入,如果还有阿里云的,就注入阿里云的即可@Resourceprivate FileService fileService;@RequestMapping("/listBuckets")public String testGetAllBuckets() throws Exception {List<String> allBucket = fileService.getAllBucket();return allBucket.get(0);}}