OSS业务存储适配器模式

流程

当我们配置了阿里云,腾讯云,minio等多个云存储厂商的业务代码时,如果我们要修改具体使用哪一种厂商的云存储,那么我们的controller层和service层就会需要改变业务代码;此时我们可以使用适配器模式来进行松耦合——>**1.**我们首先会定义一个关于文件存储的接口(非常丰富),然后定义minio,阿里云等厂商的文件存储实现类,去实现文件存储的具体细节——>**2.**那么如何确定具体使用哪一个文件存储?——>**3.**我们利用nacos动态路由,得到storage.type——>**4.**然后再在我们的StorageConfig配置类中进行判断,如果是minio的,就返回minio的业务实现类,将其注入容器中,这样就实现了我们的动态路由,我们只需修改nacos上的配置文件进行发布即可

package com.wyh.oss.adapter;

import com.wyh.oss.entity.FileInfo;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.List;

/**
 * 文件存储适配器
 *
 * @create: 2023/12/1 0:32
 */
public interface StorageAdapter {

    /**
     * 创建存储桶
     *
     * @param bucket 存储桶名称
     */
    void createBucket(String bucket);

    /**
     * 上传文件
     *
     * @param multipartFile 文件流
     * @param bucket      存储桶名称
     * @param objectName  对象名称
     */
    void uploadFile(MultipartFile multipartFile, String bucket, String objectName);

    /**
     * 获取所有存储桶
     *
     * @return 存储桶名称集合
     */
    List<String> getAllBuckets();

    /**
     * 获取存储桶下所有文件
     *
     * @param bucket 存储桶名称
     * @return 文件信息集合
     */
    List<FileInfo> getAllFiles(String bucket);

    /**
     * 下载文件
     *
     * @param bucket     存储桶名称
     * @param objectName 对象名称
     * @return 文件流
     */
    InputStream download(String bucket, String objectName);

    /**
     * 删除存储桶
     *
     * @param bucket 存储桶名称
     */
    void deleteBucket(String bucket);

    /**
     * 删除文件
     *
     * @param bucket     存储桶名称
     * @param objectName 对象名称
     */
    void deleteObject(String bucket, String objectName);

    String getUrl(String bucketName, String objectName);
}

minio的业务实现类:

package com.wyh.oss.adapter;

import com.wyh.oss.entity.FileInfo;
import com.wyh.oss.util.MinioUtil;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.InputStream;
import java.util.List;

/**
 * minioIO存储适配器
 *
 * @create: 2023/12/1 0:38
 */

public class MinioStorageAdapter implements StorageAdapter {

    @Resource
    private MinioUtil minioUtil;

    /**
     * minioUrl
     */
    @Value("${minio.url}")
    private String url;

    // 创建存储桶
    @Override
    @SneakyThrows
    public void createBucket(String bucket) {
        minioUtil.createBucket(bucket);
    }

    // 文件上传
    @Override
    @SneakyThrows
    public void uploadFile(MultipartFile multipartFile, String bucket, String objectName) {
        // 使用 minioUtil 对象创建存储桶
        minioUtil.createBucket(bucket);

        // 如果 objectName 不为空,则将文件名设置为 objectName + "/" + multipartFile.getName()
        if (objectName != null) {
            // 使用 minioUtil 对象将文件上传到 MinIO 存储服务中,并将其保存到指定的 bucket 以及 objectName + "/" + multipartFile.getName()
            minioUtil.uploadFile(multipartFile.getInputStream(), bucket, objectName + "/" + multipartFile.getName());
        } else {
            // 使用 minioUtil 对象将文件上传到 MinIO 存储服务中,并将其保存到指定的 bucket 以及 multipartFile.getName()
            minioUtil.uploadFile(multipartFile.getInputStream(), bucket, multipartFile.getName());
        }
    }
    // 获取所有存储桶
    @Override
    @SneakyThrows
    public List<String> getAllBuckets() {
        return minioUtil.getAllBucket();
    }

    // 获取所有文件
    @Override
    @SneakyThrows
    public List<FileInfo> getAllFiles(String bucket) {
        return minioUtil.getAllFile(bucket);
    }

    // 文件下载
    @Override
    @SneakyThrows
    public InputStream download(String bucket, String objectName) {
        return minioUtil.downLoad(bucket, objectName);
    }

    // 桶删除
    @Override
    @SneakyThrows
    public void deleteBucket(String bucket) {
        minioUtil.deleteBucket(bucket);
    }

    // 文件删除

    @Override
    @SneakyThrows
    public void deleteObject(String bucket, String objectName) {
        minioUtil.deleteObject(bucket, objectName);
    }

    @Override
    @SneakyThrows
    public String getUrl(String bucket, String objectName) {
        return url + "/" + bucket + "/" + objectName;
    }

}

Util中封装了所有存储的具体细节:

package com.wyh.oss.util;

import com.wyh.oss.entity.FileInfo;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * minio文件操作工具
 *
 * @author: ChickenWing
 * @date: 2023/10/11
 */
@Component
public class MinioUtil {

    @Resource
    private 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, 5242889L).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()
        );
    }

    /**
     * 获取文件url
     */
    public String getPreviewFileUrl(String bucketName, String objectName) throws Exception{
        GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
                .method(Method.GET)
                .bucket(bucketName).object(objectName).build();
        return minioClient.getPresignedObjectUrl(args);
    }

}

config的配置:

package com.wyh.oss.config;

import com.wyh.oss.adapter.AliStorageAdapter;
import com.wyh.oss.adapter.MinioStorageAdapter;
import com.wyh.oss.adapter.StorageAdapter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 文件存储config
 *
 * @create: 2023/12/1 10:35
 */
@Configuration
@RefreshScope
public class StorageConfig {

    @Value("${storage.service.type}")
    private String storageType;

    /*@Resource
    private StorageAdapter aliStorageAdapterImpl;
    @Resource
    private StorageAdapter minioStorageServiceImpl;*/

    @Bean
    @RefreshScope
    public StorageAdapter storageService() {
        if ("minio".equals(storageType)){
            return new MinioStorageAdapter();
        } else if("aliyun".equals(storageType)) {
            return new AliStorageAdapter();
        } else {
            throw new IllegalArgumentException("未配置存储服务类型");
        }
    }


}

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PHP中的工厂模式可以用于创建对象,而不需要直接使用new关键字实例化。对于使用OSS(对象存储服务)的工厂模式,你可以按照以下步骤进行操作: 1. 创建一个接口(或抽象类)来定义OSS客户端的方法,例如`OSSClientInterface`。 ```php interface OSSClientInterface { public function upload($file); // 其他操作方法 } ``` 2. 创建一个实现了该接口的具体类,例如`AliyunOSSClient`。该类应该包含具体的OSS操作逻辑。 ```php class AliyunOSSClient implements OSSClientInterface { public function upload($file) { // 实现上传文件到阿里云OSS的逻辑 } // 其他操作方法的实现 } ``` 3. 创建一个工厂类,例如`OSSClientFactory`,用于根据需要创建不同的OSS客户端对象。 ```php class OSSClientFactory { public static function createClient($provider) { switch ($provider) { case 'aliyun': return new AliyunOSSClient(); // 可以添加其他OSS服务提供商的创建逻辑 default: throw new Exception('Unsupported OSS provider'); } } } ``` 4. 在代码中使用工厂类来创建所需的OSS客户端对象。 ```php $ossProvider = 'aliyun'; // 可以根据需要设置OSS服务提供商 $ossClient = OSSClientFactory::createClient($ossProvider); // 使用ossClient进行操作 $ossClient->upload('example.jpg'); ``` 通过使用工厂模式,你可以方便地根据需要创建不同的OSS客户端对象,而无需直接实例化具体的实现类。这样可以提高代码的灵活性和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fairy要carry

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值