Spring Boot顶层接口实现类注入项目的方法
1、背景
在项目中,我们通常会具有同一特性的业务类定义一个顶层接口,让业务类实现这个接口,通过接口规范来管理这些类。我们将这些实现接口的业务类交托给Spring容器接口后,有时候需要根据业务类型来选择动态选择对应的业务类阿里处理业务。这个时候就获取到这些业务类并进行管理,在需要时取出对应的业务类处理业务。如何管理就是本期要介绍的内容。
以下是我定义的一个简单的顶层接口,它有两个方法,一个是提供类型的getType()方法,一个是处理业务的hanlde()方法。我们的任务就是对其实现类进行管理,当需要时可根据类型获取对应实现类。
public interface IBaseHandler {/*** 获取处理器类型* @return 处理器类型*/int getType();/*** 处理业务* @param t 业务数据* @param <T> 业务数据类型*/<T> void handler(T t);
}
2、简单的管理方法
我们可以通过使用@Autowired注解将所有实现了IBaseHandler接口的类注入到项目当中,并在需要时遍历业务类对象,获取对应的对象来处理业务。代码如下所示:
@Autowiredprivate List<IBaseHandler> handlers;/*** 处理业务* @param type 业务类型* @param data 业务数据* @param <T> 业务数据类型*/public <T> void handle(int type, T data) {handlers.stream().filter(handler -> handler.getType() == type).findAny().orElseThrow(() -> {// 获取不到业务类对象时打印日志并抛出异常log.error("Failed to get handler, type:{}", type);throw new NoSuchElementException("No such handler");}).handler(data);}
3、更好的管理方法
1、简单管理方法的弊端
上面的简单管理方法用起来方便,但是有两个弊端:
(1)耦合度高,所有需要使用该接口的地方都需要进行注入再遍历的过程。
(2)性能较差,每次执行业务之前都需要遍历一次列表。
2、解决
我们可以使用一个工具类,提供静态方法来获取业务类。这样所有需要获取业务类的地方,就都可以通过该工具类一步获取到所需的业务类。代码如下:
1、工具类代码
@Slf4j
public class HandlerManager {/*** 按照type映射的处理器map*/private static Map<Integer, IBaseHandler> typeHandlerMap = new HashMap<>();/*** 按照类型映射的处理器map*/private static Map<Class<IBaseHandler>, IBaseHandler> clazzHandlerMap = new HashMap<>();/*** 初始化方法,项目启动时调用该方法来初始化map* @param applicationContext spring 上下文对象*/public static void init(ApplicationContext applicationContext) {List<IBaseHandler> handlers = new ArrayList<>();applicationContext.getBeansOfType(IBaseHandler.class).forEach((name, obj) -> handlers.add(obj));// 为了方便,两次循环构建map,一次循环也可以解决,不过人为定义的handler数量不多,一次循环性能提升不大typeHandlerMap = handlers.stream().collect(Collectors.toMap(IBaseHandler::getType, obj -> obj));clazzHandlerMap = handlers.stream().collect(Collectors.toMap(obj -> (Class<IBaseHandler>) obj.getClass(), obj -> obj));}public IBaseHandler getHandlerByType(int type) {return Optional.ofNullable(typeHandlerMap.get(type)).orElseThrow(() -> {// 获取不到处理器打印日志并抛出异常log.info("Failed to get handler, type:{}", type);throw new NoSuchElementException("No such handler error");});}public IBaseHandler getHandlerByClass(Class<IBaseHandler> clazz) {return Optional.ofNullable(clazzHandlerMap.get(clazz)).orElseThrow(() -> {// 获取不到处理器打印日志并抛出异常log.info("Failed to get handler, clazz:{}", clazz);throw new NoSuchElementException("No such handler error");});}}
2、调用工具类的init方法
由于工具类提供的是静态方法,因此无法通过注入的方式来获取到所有的IBaseHanlder,所以需要借助其他可注入IBaseHanlder的类来初始化管理对象,以下是方法:
/*** 项目初始化类* 继承ApplicationContextAware,实现setApplicationContext,可获取ApplicationContext来获取上下文*/
@Component
public class ApplicationInit implements ApplicationContextAware {@Autowiredprivate List<IBaseHandler> handlers;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {// 调用处理器工具类初始化方法HandlerManager.init(applicationContext);}
}
相关文章:
Spring Boot顶层接口实现类注入项目的方法
1、背景 在项目中,我们通常会具有同一特性的业务类定义一个顶层接口,让业务类实现这个接口,通过接口规范来管理这些类。我们将这些实现接口的业务类交托给Spring容器接口后,有时候需要根据业务类型来选择动态选择对应的业务类阿里…...
JDBC介绍-AI问答(通义千问)
一、JDBC介绍 介绍JDBC JDBC(Java Database Connectivity)是Java中用于连接和操作关系型数据库的标准API(应用程序编程接口)。它是由Sun Microsystems(现在是Oracle的一部分)开发,并随Java Deve…...
Spring AI探索
Spring AI概述 该Spring AI项目旨在简化包含人工智能功能的应用程序的开发,避免不必要的复杂性。 该项目从著名的 Python 项目(例如 LangChain 和 LlamaIndex)中汲取灵感,但 Spring AI 并非这些项目的直接移植。该项目的成立基于…...
【代码随想录算法训练Day39】LeetCode 62.不同路径、LeetCode 63.不同路径II
Day39 动态规划第二天 LeetCode 62.不同路径 二维dp数组的含义:走到位置为(i,j)的格子的走法为dp[i][j]种。 递推公式:dp[i][j]dp[i-1][j]dp[i][j-1]。 初始化:dp[i][0]和dp[0][j]都赋值为1. 递归顺序:从左往右,从上…...
浙大版PTA Python程序设计 题目与知识点整理(综合版)
目录 第一章 一、高级语言程序的执行方式 二、变量赋值与内存地址 三、字符编码 3.1 Unicode 3.2 ASCII(American Standard Code for Information Interchange) 四、编程语言分类按照编程范式分类 4.1 面向过程语言 4.2 面向对象语言 五、原码…...
HTML表单深度解析:构建互动的网页界面
表单是HTML中用于收集用户输入信息的重要元素,是网页与用户交互的关键组件。以下是一个典型的HTML表单示例,我们将会详细解析其中的各个元素及属性含义。 <form action"https://xx.xxx.xx/search" target"_self" method"ge…...
git 分支管理规范
分支命名 master 分支 master 为主分支,也是用于部署生产环境的分支,需要确保master分支稳定性。master 分支一般由 release 以及 hotfix 分支合并,任何时间都不能直接修改代码。 develop 分支 develop 为开发环境分支,始终保持…...
Spring Cloud Gateway 详解:构建高效的API网关解决方案
Spring Cloud Gateway 详解:构建高效的API网关解决方案 Spring Cloud Gateway 是 Spring Cloud 生态系统中用于构建 API 网关的核心组件。它基于 Spring WebFlux 构建,旨在提供简单且有效的方式来路由和增强 API 请求。以下是 Spring Cloud Gateway 的详…...
基于Quartus Prime18.1的安装与FPGA的基础仿真教程
Quartus是一种美国科技公司Intel(英特尔)公司开发的FPGA(现场可编辑门阵列)设计编译软件,用作设计、仿真、综合和布局、支持多种编程语言,包括VHDL、Verilog等,并具有丰富的功能和工具库&#x…...
AJAX 和 XML:现代 Web 开发的关键技术
AJAX 和 XML:现代 Web 开发的关键技术 引言 在当今的 Web 开发领域,AJAX 和 XML 是两项至关重要的技术。AJAX(Asynchronous JavaScript and XML)允许网页在不重新加载整个页面的情况下,与服务器交换数据和更新部分网页内容。而 XML(eXtensible Markup Language)则是一…...
vue实现图片预览
在 Vue 中实现图片预览功能,通常涉及监听文件输入的变化,并在用户选择文件后,使用 FileReader API 来读取文件内容,然后显示这个内容作为图片的预览。以下是一个简单的 Vue 组件示例,它实现了图片预览功能:…...
C语言入门系列:流程控制
一,C代码执行顺序 默认情况下,C语言程序从main()函数开始执行,随后按源代码中语句出现的顺序逐一执行。 这意味着,如果不考虑任何控制结构,程序会自上而下,逐行执行每条语句,直到遇到函数调用…...
【深度学习】NLP,Transformer讲解,代码实战
文章目录 1. 前言2. Transformer结构训练过程1. 输入嵌入和位置编码2. 编码器层2.1 单头的注意力机制(便于理解)2.2 多头的注意力机制(Transformer真实使用的)2.3 残差连接和层归一化2.4 前馈神经网络(FFN)2.5 残差连接和层归一化2.6 总结 3. 解码器层 推…...
ES6 .entries用法
.entries() 返回数组的可迭代对象itarator,可以通过for of 来遍历数组或对象的值。但是它们的写法不一样。 数组用法 obj [apple,bananer,orange] for(let [i,v] of obj.entries()){console.log(i)console.log(v) } //输出 // 0 // apple // 1 // bananer // 2 //orange对象…...
【LeetCode 动态规划】买卖股票的最佳时机问题合集
文章目录 1. 买卖股票的最佳时机含冷冻期 1. 买卖股票的最佳时机含冷冻期 题目链接🔗 🍎题目思路: 🍎题目代码: class Solution { public:int maxProfit(vector<int>& prices) {int n prices.size();ve…...
python学习:语法(2)
目录 对象的布尔值 分支结构 双分支结构 多分支结构 嵌套if的使用 条件表达式 Pass语句 range()函数的使用 流程控制语句 对象的布尔值 Python一切皆对象,所有对象都有一个布尔值,通过内置函数bool()获取对象的布尔值 这些…...
经典电源电路基础(变压-整流-滤波-稳压)
1.电源电路的功能和组成 电子电路中的电源一般是低压直流电,先把220v交流电变换成低压直流电,再用整流电路变成脉动的直流电,最后用滤波电路滤除掉脉动直流中的交流成分后才能得到直流电。有的电子设备对电源的质量要求很高,所以…...
生成式人工智能备案办理指南,深度解析大模型备案全流程
早在2023年年初,国家互联网信息办公室、工业和信息化部、公安部针对深度合成服务制定的《互联网信息服务深度合成管理规定》(“《深度合成管理规定》”)顺利施行,其明确了深度合成服务相关方的义务与主体责任,强化了对…...
1527. 患某种疾病的患者
1527. 患某种疾病的患者 题目链接:1527. 患某种疾病的患者 代码如下: # Write your MySQL query statement below select patient_id,patient_name,conditions from Patients where conditions like "DIAB1%" or conditions like "% DI…...
【C/C++】【学生成绩管理系统】深度剖析
可接各类C/C管理系统课设 目录 实现功能 部分1:系统设置和主菜单 1. 引入头文件 2. 定义结构体 3. 函数声明 4. 主函数 部分2:添加学生信息 部分3:删除学生信息 部分4:修改学生信息 部分5:查询学生信息 部分…...
Yarbo 机器人割草机调整策略:远程后门访问功能将设为可选安装
Yarbo 调整远程后门访问功能,设为可选安装Yarbo 原有的远程后门访问功能可能使不法分子通过互联网对机器人进行重新编程。如今,该公司计划彻底移除这一功能,联合创始人肯尼斯科尔曼承诺,客户将能够决定是否一开始就安装该功能&…...
GPU流水线设计:提升深度学习计算效率的关键技术
1. GPU流水线设计基础概念现代GPU架构为深度学习工作负载提供了强大的并行计算能力,但传统的批量同步并行(BSP)执行模型存在资源利用率低下的问题。GPU流水线技术通过将计算图分解为多个阶段并在其间插入队列节点,实现了计算与通信的重叠执行。1.1 传统B…...
别再只会用WinHex看十六进制了!这5个隐藏功能帮你搞定90%的数据恢复难题
WinHex高阶数据恢复实战:5个被低估的杀手级功能解析 在数据恢复领域,WinHex早已超越了简单的十六进制编辑器定位。这款由X-Ways公司开发的专业工具集成了磁盘编辑、内存分析、数据解释等多项强大功能,但大多数用户仅停留在基础的文件浏览和简…...
【仅限首批内测团队获取】AI Agent Serverless标准化交付套件(含Terraform模块+OpenTelemetry追踪模板+合规审计清单)
更多请点击: https://intelliparadigm.com 第一章:AI Agent Serverless应用的演进逻辑与范式跃迁 AI Agent 与 Serverless 的融合并非技术堆叠,而是计算范式在智能体自治性、事件驱动粒度和资源契约关系三重维度上的结构性重构。早期云函数仅…...
ElevenLabs Starter计划实战指南(新手必看的4步激活+2次配额翻倍技巧)
更多请点击: https://intelliparadigm.com 第一章:ElevenLabs Starter计划的核心定位与适用边界 ElevenLabs Starter 计划是面向开发者、内容创作者及小型团队推出的免费语音合成入门方案,旨在以零门槛方式提供高质量、低延迟的文本转语音&…...
北京数据恢复公司哪个公司好
在当今数字化时代,数据的重要性不言而喻。无论是个人用户的珍贵照片、文档,还是企业的重要商业数据,一旦丢失,都可能造成巨大的损失。在北京,有众多的数据恢复公司,那么哪家公司才是最好的选择呢࿱…...
DeepSeek Clean Code终极阈值(v2.3.1正式版):超出3个指标即触发强制重构——你达标了吗?
更多请点击: https://intelliparadigm.com 第一章:DeepSeek Clean Code终极阈值的演进与哲学内核 DeepSeek Clean Code 的“终极阈值”并非静态指标,而是代码可维护性、语义清晰度与执行确定性三者动态收敛的临界点。它源于对 LLM 推理链中 …...
开源OmenSuperHub:解决惠普OMEN笔记本性能限制的完整技术方案
开源OmenSuperHub:解决惠普OMEN笔记本性能限制的完整技术方案 【免费下载链接】OmenSuperHub 使用 WMI BIOS控制性能和风扇速度,自动解除DB功耗限制。 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 第一部分:技术挑战分…...
AI应用开发平台RiserFlow实战:从架构解析到智能客服构建
1. 项目概述:从“RiserFlow”看现代AI应用开发范式的演进最近在GitHub上看到一个挺有意思的项目,叫riserlabs/riserflow。光看这个名字,可能有点摸不着头脑,但如果你点进去,会发现它其实指向一个更具体的产品ÿ…...
新媒体编辑提效:OpenClaw批量剪辑短视频、生成文案字幕,适配多平台发布规则
新媒体编辑效率革命:OpenClaw赋能短视频批量剪辑、智能文案生成与多平台适配在信息爆炸、注意力稀缺的移动互联网时代,短视频已成为内容传播的绝对主力军。对于新媒体运营团队而言,高效地产出高质量、符合各平台调性且能快速发布的短视频内容…...
