OSS模块扩展 -- 传统Service下的问题

211 阅读1分钟

一、前言

minio入门中,已经完成了MinioUtil(原子类,直接与minio交互,相当于dao层)的封装,在此基础上,还要进行service层的组装。

二、service层组装

为了方便切换任何一个oss,我们将公共方法抽取为接口,由某个oss的实现类去编写具体逻辑

public interface StorageService {
    /**
     * 创建bucket
     * @param bucket
     */
    void createBucket(String bucket);

    /**
     * 上传文件
     * @param multipartFile
     * @param bucket
     * @param objectName
     */
    void uploadFile(MultipartFile multipartFile, String bucket, String objectName);
}

aliOss实现类

@Service("aliStorageServiceImpl")
public class AliStorageServiceImpl implements StorageService {

    @Override
    public void createBucket(String bucket) {

    }

    @Override
    public void uploadFile(MultipartFile multipartFile, String bucket, String objectName) {

    }
}

Minio实现类

@Service("minioStorageServiceImpl")
public class MinioStorageServiceImpl implements StorageService {

    @Resource
    private MinioUtil minioUtil;

    @Override
    @SneakyThrows //Lombok中的注解 会在编译期补上异常处理
    public void createBucket(String bucket) {
        minioUtil.createBucket(bucket);
    }
    

    /**
     * 上传文件
     * @param multipartFile
     * @param bucket
     * @param objectName 为空,文件路径为根目录;不为空,文件路径为objectName目录下
     */
    @Override
    @SneakyThrows
    public void uploadFile(MultipartFile multipartFile, String bucket, String objectName) {
        minioUtil.createBucket(bucket);
        if(objectName != null) {
            minioUtil.uploadFile(multipartFile.getInputStream(), bucket, objectName + "/" + multipartFile.getOriginalFilename());
        } else {
            minioUtil.uploadFile(multipartFile.getInputStream(), bucket, multipartFile.getOriginalFilename());
        }
    }

}

三、Controller层问题

由于多个OSS实现类都实现了StorageService类,在Controller层引入的StorageService对象后由于Spring容器不清楚具体实现哪个类会报错。

解决方案: 在每个OSS实现类中声明名字

@Service("aliStorageServiceImpl")
public class AliStorageServiceImpl implements StorageService
@Service("minioStorageServiceImpl")
public class MinioStorageServiceImpl implements StorageService

由于@Resource注解是按名称注入,所以可将对象名设置为与实现类@Service注解上自定义的名称对应来进行注入。

@RestController
public class FileController {
    @Resource //根据名称注入
    private StorageService minioStorageServiceImpl;

    @PostMapping("/upload")
    public void test() throws Exception {
        minioStorageServiceImpl.createBucket("ssm");
    }
}

当文件Controller过多时,想要切换OSS的实现类,要手动修改每一个StorageService的对象名称,太过繁琐,这时可通过 适配器模式 + Nacos动态配置读取的方式来解决