首页 > 其他分享 >[纯干货]SpringCould + 适配器模式 + nacos动态部署 OSS 对接

[纯干货]SpringCould + 适配器模式 + nacos动态部署 OSS 对接

时间:2024-08-11 12:57:53浏览次数:12  
标签:String SpringCould 适配器 bucket nacos minioUtil Override public

一、前言

在一个微服务项目里,我们的 OSS 云存储服务常常需要配置诸如阿里云、腾讯云、minio 等多个云存储厂商的业务代码,而且后续无法确保是否会增添新的云存储厂商。此时,倘若我们要修改具体使用的云存储厂商,就会致使 controller 层和 service 层发生变动,这并不符合低耦合的理念。在这种情况下,我们完全可以采用适配器模式来开展项目开发!

比如:假设我们最初使用的是阿里云的云存储服务,后续要切换为腾讯云。如果没有采用适配器模式,那么在修改配置时,就会直接抛出 erro 99+,需要在 controller 层和 service 层大量修改代码,涉及到与云存储交互的逻辑都需要重新调整。而通过适配器模式,我们可以将不同云存储厂商的接口适配为统一的接口,这样在切换时,只需修改少量的配置或者适配器的实现,大大降低了代码的改动范围和维护成本。

这里我的项目以minio + aliyun为例,结合nacos动态部署+适配器模式完成。

二、适配器模式

适配器模式我们可以理解为一个桥梁,是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。

举一个很贴切的例子,在中国,家用电的电压是220V,但是在美国,他们的家用电压为110V,因此如果我们要想在国外也能达到国内一样的充电体验,我们可能需要购买一个适配器,来将110V电压转换为220V,那么这个案例就是一个简单的适配器模式

三、项目实战

我们先新建一个文件存储的适配器 (Adapter),这个适配器我们创建了一些基础的方法,例如上传下载、查询等等

/**
 * 文件存储适配器
 */
public interface StorageAdapter {

    /**
     * 创建bucket桶
     */
    void createBucket(String bucket);

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

    /**
     * 列出所有桶
     */
     List<String> getAllBucket();

    /**
     * 列出当前桶及文件
     */
     List<FileInfo> getAllFile(String bucket);

    /**
     * 下载文件
     */
     InputStream downLoad(String bucket, String objectName);

    /**
     * 删除桶
     */
     void deleteBucket(String bucket) ;

}

 然后我们需要简历对应的云存储实现类去实现适配器,并且重写对应对应方法

/**
 * minio文件存储适配器
 */
public class MinioStorageAdapter implements StorageAdapter{

    @Resource
    private MinioUtil minioUtil;

    @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.createBucket(bucket);
        if ( objectName != null ){
            minioUtil.uploadFile(multipartFile.getInputStream(),bucket,objectName + "/" + multipartFile.getOriginalFilename());
        }else{
            minioUtil.uploadFile(multipartFile.getInputStream(),bucket,multipartFile.getOriginalFilename());
        }
    }

    @Override
    @SneakyThrows
    public List<String> getAllBucket() {
        return minioUtil.getAllBucket();
    }

    @Override
    @SneakyThrows
    public List<FileInfo> getAllFile(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);
    }

}

这里我们在实现一个阿里云的接口,等会就用minio+阿里云进行测试,这里只用作测试,所以很多方法都没实现

/**
 * 阿里文件存储适配器
 */
public class AliStorageAdapter implements StorageAdapter{
    @Override
    public void createBucket(String bucket) {

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

    }
    @Override
    public List<String> getAllBucket() {
        List<String> bucketNameList = new LinkedList<>();
        bucketNameList.add("aliyun");
        return bucketNameList;
    }

    @Override
    public List<FileInfo> getAllFile(String bucket) {
        return null;
    }

    @Override
    public InputStream downLoad(String bucket, String objectName) {
        return null;
    }

    @Override
    public void deleteBucket(String bucket) {

    }
}

然后就来到一个问题,就是怎么分辨到底是用aliyun的oss还是minio的呢?

这里我们就要创建一个配置类,在配置类中使用Value属性去读取配置的oss对象,然后通过@RefreshScope注解可以动态刷新bean,然后进行判断,满足条件的就new一个对象

/**
 * 适配器config
 */
@Configuration
@RefreshScope
@EnableAutoConfiguration
public class StorageConfig {

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

    @Bean
    @RefreshScope
    public StorageAdapter storageAdapter(){
        if ("minio".equals(storageType)){
            return new MinioStorageAdapter();
        } else if ("aliyun".equals(storageType)) {
            return new AliStorageAdapter();
        }else {
            throw new  IllegalArgumentException("未找到对应的文件存储服务器");
        }
    }
}

注:这里我是用的是动态部署,所以我的{storage.service.type}字段是配置在nacos上的,所以我使用@RefreshScope可以做到不重启项目去动态的更改配置,动态刷新

 然后我们在  fileservice 层就可以使用我们的适配器模式进行业务方法的实现。

@Service
public class FileService {


    private final StorageAdapter storageAdapter;

    public FileService(StorageAdapter storageAdapter){
        this.storageAdapter = storageAdapter;
    }

    /**
     * 列出所有桶
     */
    public List<String> getAllBucket() {
        return storageAdapter.getAllBucket();
    }

controller 我们也是调用 fileservice 方法

@RestController
public class FileController {
    @Resource
    private MinioUtil minioUtil;

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

    @RequestMapping("/testGetAllBuckets")
    public String testGetAllBuckets() throws Exception {
        List<String> bucket = fileService.getAllBucket();
        return bucket.get(0);
    }

这样适配器模式就搭建完成啦,小伙伴们快去试试吧!

标签:String,SpringCould,适配器,bucket,nacos,minioUtil,Override,public
From: https://blog.csdn.net/indexqian/article/details/141098584

相关文章

  • Sentinel 规则持久化到 Nacos 实战
    前言:前面系列文章我们对Sentinel的作用及工作流程源码进行了分析,我们知道Sentinel的众多功能都是通过规则配置完成的,但是我们前面在演示的时候,发现Sentinel一重启,配置的规则就没有了,这是因为规则存储在内存中,本篇我们来实现Sentinel规则持久化到Nacos中。Sentin......
  • Spring Cloud接入Nacos作为配置中心和服务发现
    一、nacos介绍Nacos是DynamicNamingandConfigurationService(动态命名和配置服务)的首字母简称,它是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos由阿里巴巴开源,致力于帮助用户发现、配置和管理微服务。以下是Nacos的详细介绍:动态服务发现:Nacos......
  • docker启动服务,nacos注册地址默认是容器内IP
    在使用Nacos注册服务时,通常是因为Nacos在Docker中运行时,默认会使用容器的网络设置。本机ip是:192.168.16.163但发现注册到nacos上ip却变了,这样的话调用这个服务是调不同的,除非建docker网络 实现宿主机ip注册的方法:docker-compose问价设置宿主机ipversion:'3......
  • 服务治理-Nacos
    介绍思考什么是服务治理常见的注册中心ZonnkeeperEurekaConsullNacos(服务治理配置中心)Nacos实战入门修改bin–>startup.smd把集群模式改为单列模式问题:如果出现一闪而过,要看jdk环境变量有没有配置,jdk是不是8以上双击会出现一个黑窗口–里面......
  • 高性能USB转串口适配器,让USB和串行接口轻松实现双向通信!
    多功能数字接口转发器,让USB和串行接口轻松实现双向通信!高性能USB转串口适配器,助力你的嵌入式程序开发!USB转串口适配器可编程开发板TYPE接口是一种多功能的数字接口物理层协议转发器,可以转换USB接口和串行接口之间的双向通信。它支持多种嵌入式程序开发,并可以自由制定转发透传逻......
  • Dubbo&Nacos
    Dubbo的前世今生2011年10月27日,阿里巴巴开源了自己的SOA服务化治理方案的核心框架Dubbo,服务治理和SOA的设计理念开始逐渐在国内软件行业中落地,并被广泛应用。早期版本的dubbo遵循SOA的思想,是面向服务架构的重要组件。如今版本的Dubbo作为SpringCloud的二进制通信方案来发......
  • Android开发 - (适配器)ArrayObjectAdapter类与Presenter实现类关联的作用解析
    ListRowPresenterArrayObjectAdapteradapter=newArrayObjectAdapter(newListRowPresenter());用途:用于展示ListRow中的水平滚动列表项ImageCardViewPresenterArrayObjectAdapteradapter=newArrayObjectAdapter(newImageCardViewPresenter());用途:用于显示带......
  • Android开发 - (适配器)Adapter类中ArrayObjectAdapter实现类详细解析
    简介用于AndroidTV的Leanback库,用于绑定对象数组到UI组件具体作用ArrayObjectAdapter是RecyclerView和Adapter系列中用于处理列表数据的一种适配器类型,主要用于AndroidTV的Leanback库中的BrowseFragment、DetailFragment和PlaybackOverlayFragment等......
  • SpringCloud使用Sentinel,Sentinel持久化,Sentinel使用nacos持久化
    Sentinel官方文档:https://sentinelguard.io/zh-cn/docs/introduction.html下载Sentinel:https://github.com/alibaba/Sentinel/releasessentinel控制台文档:https://sentinelguard.io/zh-cn/docs/dashboard.html参考:https://www.cnblogs.com/ralgo/p/14152390.html启动Sentinel命令:j......
  • 本地部署动态服务发现管理平台Nacos结合内网穿透实现远程访问管理
    文章目录前言1.Docker运行Nacos2.本地访问Nacos3.Linux安装Cpolar4.配置NacosUI界面公网地址5.远程访问NacosUI界面6.固定NacosUI界面公网地址7.固定地址访问Nacos前言本文主要介绍如何本地部署动态服务发现、配置管理和服务管理平台Nacos,并结合cpola......