【Spring 接口多实现】怎么优雅的获取接口的多实现

使用 Spring 优雅获取接口的多现实

java 一个最显著的特征是面向接口编程。如果业务中一个接口有多个实现,我们怎么处理?

1、设计模式之 工厂模式?策略模式?
2、Spring 注入给不同的实现使用不同的命名?
3、。。。

以上的方式是不是都免不了写 if else,那有没有优雅一点的方式呢,下面就举例介绍:

ISyncInfoService , 同步信息的接口:

public interface ISyncInfoService  {
	/**
	 * 执行信息同步
	 */
	void execute(SyncObj syncObj);

	/**
	 * 用以区分不同实现不同的 type,以便 Factory 可以获取到正确的 ISyncInfoService 实现
	 */
	SyncTypeEnum getType();
}

同步信息有多个实现,需要根据不同的场景给不同的第三方同步数据,需要实现 ISyncInfoService 接口
PartnerA

public class SyncInfo2PartnerAService implements ISyncInfoService {
	public void execute(SyncObj syncObj) {
		//TODO sync Info to Partner A
		// 可能要有不同的业务逻辑, 假设 Partner A 提供的是 RPC 接口
	}
	
	public SyncTypeEnum getType() {
		return SyncTypeEnum.TYPE_A;
	}
}

PartnerB

public class SyncInfo2PartnerBService implements ISyncInfoService {
	public void execute(SyncObj syncObj) {
		//TODO sync Info to Partner B
		// 可能要有不同的业务逻辑,假设 Partner B 提供的是 http 服务
	}
	public SyncTypeEnum getType() {
		return SyncTypeEnum.TYPE_B;
	}
}
public enum SyncTypeEnum {
	// 演示类型,根据自己业务定义
	TYPE_A(1, "sync to a"),
	TYPE_B(2, "sync to b"),
	;

	private int code;
	private String desc;
	
	SyncTypeEnum(int code, String desc) {
		this.code = code;
		this.desc = desc;
	}
	public int getCode() {
		return this.code;
	}
	
	public int getTypeBySource(int source) {
		SyncTypeEnum[] var1 = values();
        int var2 = var1.length;

        for(int var3 = 0; var3 < var2; ++var3) {
            SyncTypeEnum enu = var1[var3];
            if (enu.getCode() == id) {
                return enu;
            }
        }
        return null;
	}
}
@Component
public class SyncInfoServiceFactory implements ApplicationContextAware {

    private static Map<SyncTypeEnum, ISyncInfoService> serviceMap;

    public static <T extends ISyncInfoService> T getService(SyncTypeEnum source) {
        return (T) serviceMap.get(source);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    	// 服务启动自动获取 ISyncInfoService 对应的实现,放入到 serviceMap 中,后期使用直接从 serviceMap 中 get
        Map<String, ISyncInfoService> beansOfType = applicationContext.getBeansOfType(ISyncInfoService.class);
        serviceMap = new HashMap<>();
        beansOfType.forEach((key, value) -> serviceMap.put(value.getType(), value));
    }
}

调用者 BusinessCenterService
调用 ISyncInfoService#execute() 根据不同的场景使用 A 或 B,不使用 if else

@Component
public class BusinessCenterService {
	
	public void syncInfo2Partner(BuinsessObj bo) {
		// 通过 SyncInfoServiceFactory ,根据不同的入参 source 值从 serviceMap 中获取对应 实现
		ISyncInfoService syncInfoService = SyncInfoServiceFactory.getService(SyncTypeEnum.getTypeBySource(bo.getSource()));
        if (orderSyncService != null) {
        	SyncObj so = null;
        	// TODO 构造要同步的 so 信息
			syncInfoService.execute(so);
		}
	}
}

public class BuinessObj {
	private int source;
	//TODO ...
	public int getSource () {
		return this.source;
	}
}

以上就是在 Spring 中注入方式的一个接口,多个实现时,完成不同的业务的实现,利用 ApplicationContext#getBeansOfType 获取实现的方式,可以使用在对外提供统一接口,内部路由的方式;也可使用在不同的业务的不同阶段;或者是需要调用不同的第三方接口或服务完成业务信息同步等。快来试试改造你的 if else 逻辑吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/916763.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python如何从HTML提取img标签下的src属性

目录 前提准备步骤1. 解析HTML内容2. 查找所有的img标签3. 提取src属性 完整代码 前提准备 在处理网页数据时&#xff0c;我们经常需要从HTML中提取特定的信息&#xff0c;比如图片的URL。 这通常通过获取img标签的src属性来实现。 在开始之前&#xff0c;你需要确保已经安装…

web——upload-labs——第五关——大小写绕过绕过

先上传一个 先尝试直接上传一个普通的一句话木马 不行 可以看到&#xff0c;.htaccess文件也被过滤了&#xff0c;我们来查看一下源码 第五关的源码没有把字符强制转换为小写的语句&#xff1a; $file_ext strtolower($file_ext); //转换为小写 直接通过Burpsuite抓包修改文…

C#/WinForm拖拽文件上传

一、首先创建一个上传文件的类&#xff0c;继承Control类&#xff0c;如下&#xff1a; public class UploadControl : Control{private Image _image;public UploadControl(){this.SetStyle(ControlStyles.UserPaint | //控件自行绘制&#xff0c;而不使用操作系统的绘制Cont…

oracle查询字段类型长度等字段信息

1.查询oracle数据库的字符集 SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER NLS_CHARACTERSET; 2.查询字段长度类型 SELECT * FROM user_tab_columns WHERE table_name user AND COLUMN_NAME SNAME 请确保将user替换为您想要查询的表名。sname为字段名 这里的字…

大模型基础BERT——Transformers的双向编码器表示

大模型基础BERT——Transformers的双向编码器表示 整体概况 BERT&#xff1a;用于语言理解的深度双向Transform的预训练 论文题目&#xff1a;BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding Bidirectional Encoder Representations from…

Ceph层次架构分析

Ceph的层次结构可以从逻辑上自下向上分为以下几个层次&#xff1a; 一、基础存储系统RADOS层 功能&#xff1a;RADOS&#xff08;Reliable Autonomic Distributed Object Store&#xff09;是Ceph的底层存储系统&#xff0c;提供了分布式存储的核心功能。它是一个完整的对象存…

实验6记录网络与故障排除

实验6记录网络与故障排除 实验目的及要求&#xff1a; 通过实验&#xff0c;掌握如何利用文档记录网络设备相关信息并完成网络拓扑结构的绘制。能够使用各种技术和工具来找出连通性问题&#xff0c;使用文档来指导故障排除工作&#xff0c;确定具体的网络问题&#xff0c;实施…

【前端】技术演进发展简史

一、前端 1、概述 1990 年&#xff0c;第一个web浏览器诞生&#xff0c;Tim 以超文本语言 HTML 为基础在 NeXT 电脑上发明了最原始的 Web 浏览器。 1991 年&#xff0c;WWW诞生&#xff0c;这标志着前端技术的开始。 前端&#xff08;Front-end&#xff09;和后端&#xff08;…

【笔记】关于git和GitHub和git bash

如何推送更新的代码到github仓库 如何在此项目已经提交在别的远程仓库的基础上更改远程仓库地址&#xff08;也就是换一个远程仓库提交&#xff09; 如何删除github中的一个文件 第二版 删除github上的一个仓库或者仓库里面的某个文件_github仓库删除一个文件好麻烦-CSDN博客 …

Chromium 中sqlite数据库操作演示c++

本文主要演示sqlite数据库 增删改查创建数据库以及数据库表的基本操作&#xff0c;仅供学习参考。 一、sqlite数据库操作类封装&#xff1a; sql\database.h sql\database.cc // Copyright 2012 The Chromium Authors // Use of this source code is governed by a BSD-sty…

谷歌Gemini发布iOS版App,live语音聊天免费用!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;专注于分享AI全维度知识&#xff0c;包括但不限于AI科普&#xff0c;AI工…

autoDL微调训练qwen2vl大模型

autodl是一家GPU服务厂商&#xff0c;提供专业的GPU租用服务&#xff0c;秒级计费、稳定好用 先去autodl把官方的帮助文档看懂先 AutoDL帮助文档 autodl注册并登陆&#xff0c;充钱&#xff0c;根据自己的情况租用新实例 创建新实例后马上关机&#xff0c;因为有个省钱的办法…

使用大语言模型创建 Graph 数据

Neo4j 是开源的 Graph 数据库&#xff0c;Graph 数据通过三元组进行表示&#xff0c;两个顶点一条边&#xff0c;从语意上可以理解为&#xff1a;主语、谓语和宾语。GraphDB 能够通过图来表达复杂的结构&#xff0c;非常适合存储知识型数据&#xff0c;本文将通过大语言实现图数…

RDIFramework.NET Web敏捷开发框架 V6.1发布(.NET6+、Framework双引擎)

RDIFramwork.NET Web敏捷开发框架V6.1版本发布&#xff0c;本次版本更新得非常多&#xff0c;主要有全面重新设计业务逻辑代码&#xff0c;代码量减少一半以上&#xff0c;开发更加高效。底层引入最易上手的ORM框架SqlSugar&#xff0c;让开发更加便利高效。同时保持与前期版本…

vscode-相关自用插件(倒计时,时间显示,编码对齐,css等编码颜色,简体中文,git提交相关,vue项目)

1.倒计时插件 2.时间显示插件 3.编码对齐格式颜色条 4.css等编码颜色 5.简体中文 6.git提交相关 7.vue项目

推荐一款优秀的Flash幻灯片制作软件:Flash Gallery Factory

iPixSoft Flash Gallery Factory是一款优秀的Flash幻灯片制作软件&#xff0c;可以把图片变换成绚丽多彩的Flash幻灯片和Flash相册&#xff0c;并带有动画模板、过渡效果、装饰及背景音乐等功能&#xff0c;是一款不容错过的软件。 iPixSoft Flash Gallery Factory是一款最佳的…

【Linux】man 手册的使用指南

man 手册的使用指南 man手册中文版上传至资源&#xff08;用心整理&#xff0c;感谢理解&#xff01;&#xff09; man手册官方下载链接&#xff1a;https://mirrors.edge.kernel.org/pub/linux/docs/man-pages/ man 手册页&#xff1a;https://linux.die.net/man/ Linux man…

机器学习-35-提取时间序列信号的特征

文章目录 1 特征提取方法1.1 特征提取过程1.2 两类特征提取方法2 基于数据驱动的方法2.1 领域特定特征提取2.2 基于频率的特征提取2.2.1 模拟信号2.2.2 傅里叶变换2.2.3 抽取最大幅值对应特征2.2.4 抽取峰值幅值对应特征2.3 基于统计的特征提取2.4 基于时间的特征提取3 参考附录…

redis序列化数据查询

可以看到是HashMap&#xff0c;那么是序列化的数据 那么我们来获得反序列化数据 import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.ObjectInputStream; import redis.clients.jedis.Jedis;public class RedisDeserializeDemo {public static…

vue3 中直接使用 JSX ( lang=“tsx“ 的用法)

1. 安装依赖 npm i vitejs/plugin-vue-jsx2. 添加配置 vite.config.ts 中 import vueJsx from vitejs/plugin-vue-jsxplugins 中添加 vueJsx()3. 页面使用 <!-- 注意 lang 的值为 tsx --> <script setup lang"tsx"> const isDark ref(false)// 此处…