工厂+策略模式之最佳实践(疾病报卡维护模块API设计)

目录

💻业务场景

🔧应用技术

⚙概要流程

❗开发注意

服务类上标注了 自定义注解 却无法直接利用getDeclaredAnnotation 获取

*Spring代理机制

代理机制的工作原理

代理的工作机制

代理的使用场景

已获取EmrXXXServiceImpl 的Class,如何获取public class EmrXXXServiceImpl extends ServiceImpl implements EmrXXXService 泛型类型:EmrXXX,>


💻业务场景

        某医院急诊系统需要于诊断列表关联相关疾病报卡,并且当诊断提交后,支持医生进行报卡的维护,可与HIS系统端的公卫下疾病报卡管理模块进行联动。
        经调研,考虑各个报卡的新增操作的数据流(各个报卡对应的数据库表不一)有出入,相关业务流一致,则可利用设计模式中的策略+工厂模式,以及泛型、反射、注解等技术实现相关上层API的设计。到达代码简洁,避免硬编码,且更易于扩展和支持更多类型的报卡的目的。

        利用自定义报卡标识注解将每个服务的实例化逻辑封装成不同的策略类;利用仿写Spring Bean工厂的方式,通过依赖注入和组件扫描来自动管理 Bean 的创建和查找,利用符合单一性原则自定义注解,服务类自行声明它们所支持的疾病类型,工厂可动态根据已报卡的服务去初始化报卡服务实例。

🔧应用技术

  • 枚举:报卡相关固化数据的常量(提高代码可读性和可维护性、增强类型安全、简化代码)
  • 泛型:API设计,以此提供更加灵活和通用的接口,实现接口通用。注意泛型擦除机制
  • 反射:灵活获取指定类对象,进行类之父类上的泛型Type的获取等操作
  • 注解:是标识各个报卡服务,支持后续Bean工厂初始化集合存储报卡Service Bean
  • 框架:Spring、Mybatis Plus

⚙概要流程

❗开发注意

服务类上标注了 自定义注解 却无法直接利用getDeclaredAnnotation 获取

已知注解于类的声明处,并且继承链无误(Java 的注解默认不会被继承,除非使用 @Inherited 元注解),注解作用范围为 ElementType.TYPE,并且保留策略是 RetentionPolicy.RUNTIME

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SupportedDiseaseType {String value();
}

最终定位错误为Spring 使用代理机制来管理 Bean,从而导致注解无法直接通过 getDeclaredAnnotation 获取。特别是当使用 CGLIB 代理时,代理类不会继承原始类的注解。

则利用Spring 提供了 AnnotatedElementUtils 工具类,它可以更可靠地获取注解,包括处理代理类的情况。

SupportedDiseaseType annotation = AnnotatedElementUtils.findMergedAnnotation(service.getClass(), SupportedDiseaseType.class);

*Spring代理机制

Spring 使用代理机制来管理 Bean,主要是为了实现 AOP(面向切面编程)和事务管理等功能。Spring 的代理机制允许在不修改原有代码的基础上,动态地为目标对象添加额外的功能,比如日志记录、性能监控、事务管理等。

代理机制的工作原理

Spring 中的代理有两种常见的方式:

1. JDK 动态代理(基于接口):
   - 通过反射机制创建一个实现目标对象接口的代理类,并将代理类与目标对象绑定。
   - 适用于目标类实现了接口的情况。

2. CGLIB 代理(基于子类):
   - 通过继承目标类,动态创建一个目标类的子类,并在该子类中织入增强代码。
   - 适用于目标类没有实现接口的情况,或者目标类没有实现接口但需要增强的情况。

Spring 通过这两种代理方式在运行时动态地生成代理对象,来增强目标对象的行为。代理对象和目标对象的使用是透明的,开发者只需要关注接口或原有类,Spring 会自动为其注入代理功能。

代理的工作机制

- **生成代理对象**:Spring 使用 JDK 动态代理或 CGLIB 代理创建一个代理对象,这个对象通常是目标对象的一个包装。
- **拦截方法调用**:每次调用代理对象的方法时,Spring 会通过代理对象执行相关的增强逻辑,例如日志、事务、权限控制等。
- **目标方法执行**:增强逻辑执行完毕后,代理对象会调用目标对象的实际方法。

代理的使用场景

1. AOP(面向切面编程):
   - 使用 Spring 的 AOP 可以在运行时动态地为对象添加横切关注点(如日志、事务等),而不修改目标对象的源代码。
   
2. 事务管理:
   - Spring 可以通过代理机制来自动管理数据库事务,确保在方法执行过程中根据需要进行事务的开启、提交或回滚。
   
3. 懒加载:
   - 代理对象可以通过懒加载的方式,在实际调用方法时才去创建目标对象,从而提高系统性能。

已获取EmrXXXServiceImpl 的Class,如何获取public class EmrXXXServiceImpl extends ServiceImpl<EmrXXXMapper, EmrXXX> implements EmrXXXService 泛型类型:EmrXXX

直接上代码!

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;public class Main {public static void main(String[] args) {// 假设你已经通过 AOP 得到了 `EmrXXXServiceImpl` 的 Class 对象Class<?> targetClass = EmrXXXServiceImpl.class;// 获取父类的类型参数Type genericSuperclass = targetClass.getGenericSuperclass();// 检查是否是带有泛型的类if (genericSuperclass instanceof ParameterizedType) {ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;// 获取泛型参数类型Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();// 这里假设第一个泛型参数是 `EmrXXXMapper`// 第二个泛型参数是 `EmrXXX`Type secondGenericType = actualTypeArguments[1];// 输出泛型类型的类if (secondGenericType instanceof Class<?>) {Class<?> EmrXXXClass = (Class<?>) secondGenericType;System.out.println("泛型中的 EmrXXX 的类是: " + EmrXXXClass.getName());}}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ARM异常处理 M33

1. ARMv8-M异常类型及其详细解释 ARMv8-M Exception分为两类&#xff1a;预定义系统异常(015)和外部中断(1616N)。 各种异常的状态可以通过Status bit查看&#xff0c;获取更信息的异常原因&#xff1a; CFSR是由UFSR、BFSR和MMFSR组成&#xff1a; 下面列举HFSR、MMFSR、…

【单片机通讯协议】—— 常用的UART/I2C/SPI等通讯协议的基本原理与时序分析

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、通信基本知识1.1 MCU的参见外设1.2 通信的分类按基本的类型从传输方向上来分 二、UART&#xff08;串口通讯&#xff09;2.1 简介2.2 时序图分析2.3 UART的…

Adversarial Machine Learning(对抗机器学习)

之前把机器学习&#xff08;Machine Learning&#xff09;的安全问题简单记录了一下&#xff0c;这里有深入研究了一些具体的概念&#xff0c;这里记录一下方便以后查阅。 Adversarial Machine Learning&#xff08;对抗机器学习&#xff09; Adversarial Examples 相关内容Eva…

【Go】context标准库

文章目录 1. 概述1.1 什么是 Context1.2 设计原理1.3 使用场景1.4 Context 分类核心:Context接口2. 源码解读4个实现emptyCtxTODO 和 BackgroundcancelCtxWithCancelcancelCtx.propagateCancel 构建父子关联parentCancelCtx 获取父上下文中的内嵌cancelCtxcanceltimerCtxWithT…

解决 vue3 中 echarts图表在el-dialog中显示问题

原因&#xff1a; 第一次点开不显示图表&#xff0c;第二次点开虽然显示图表&#xff0c;但是图表挤在一起&#xff0c;页面检查发现宽高只有100px,但是明明已经设置样式宽高100% 这可能是由于 el-dialog 还没有完全渲染完成&#xff0c;而你的 echarts 组件已经开始尝试渲染图…

计算机网络习题( 第3章 物理层 第4章 数据链路层 )

第3章 物理层 一、单选题 1、下列选项中&#xff0c;不属于物理层接口规范定义范畴的是&#xff08; &#xff09;。 A、 接口形状 B、 引脚功能 C、 传输媒体 D、 信号电平 正确答案&#xff1a; C 2、在物理层接口特性中&#xff0c;用于描述完成每种功能的事件发…

通俗易懂!使用Excel和TF实现Transformer

本文旨在通过最通俗易懂的过程来详解Transformer的每个步骤&#xff01; 假设我们在做一个从中文翻译到英文的过程&#xff0c;我们的词表很简单如下&#xff1a; 中文词表&#xff1a;[机、器、学、习] 英文词表[deep、machine、learning、chinese] 先来看一下Transformer的…

智慧楼盘二维、三维组件融合 720三维全景可视化

本系统通过数字孪生技术&#xff0c;实现小区楼盘系统的可视化展示&#xff0c;整合楼盘内各个系统的数据源&#xff0c;将楼盘模型与房间模型、720三维全景图相结合&#xff0c;实现了从楼盘周边到室内布局的全方位展示&#xff0c;为购房者提供全方位的可视化信息。 整个项目…

QT QCombox QSS样式问题

/*combobox 样式*/ QComboBox#FileterComboBox,QComboBox#DateRangeComboBox{background-color: #262626; /* 背景颜色 */color: #e0e0e0; /* 文本颜色 */border-radius:16px;font-family: "Microsoft YaHei"; /* 文本字体族 */font-size: 18px; /* 文…

Unittest02|TestSuite、TestRunner、HTMLTestRunner、处理excel表数据、邮件接收测试结果

目录 八、测试套件TestSuite和测试运行器TestRunner 1、基本概念 2、创建和使用测试套件 3、 自动发现测试用例、创建测试套件、运行测试 4、生成html的测试报告&#xff1a;HTMLTestRunner 1️⃣导入HTMLTestRunner模块 2️⃣运行测试用例并生成html文件 九、unittest…

NIPS2014 | GAN: 生成对抗网络

Generative Adversarial Nets 摘要-Abstract引言-Introduction相关工作-Related Work对抗网络-Adversarial Nets理论结果-Theoretical Results实验-Experiments优势和不足-Advantages and disadvantages缺点优点 结论及未来工作-Conclusions and future work研究总结未来研究方…

【已解决】pyinstaller打包ico图片报错:OSError: [WinError 225] 无法成功完成操作,因为文件包含病毒或潜在的垃圾软件。

起因&#xff1a; pyinstaller加上 --icon 参数打包时报错。 命令如下&#xff1a; 解决&#xff1a; 关闭 Windows 的病毒防护即可&#xff0c;步骤如下。 点屏幕右下角通知栏&#xff0c;进入“病毒和威胁防护”&#xff1a; 打开&#xff1a; 关闭实时保护&#xff08…

011-spring-整合三方框架的命名空间原理(重要)

根据context标签来学习了解 <context:property-placeholder location"jdbc.properties"/> <bean id"dataSource" class"com.alibaba.druid.pool.DruidDataSource"><property name"driver" value"${db.driver}&quo…

No.29 笔记 | CTF 学习干货

大家好呀&#xff01;我刚参加了美国线上CTF比赛&#xff0c;收获超多&#xff0c;特别感谢老师教我的干货知识。今天就和大家分享我的学习笔记。CTF像刺激冒险&#xff0c;有挑战有惊喜。 学习中我懂了很多知识技能&#xff0c;像密码学、Web安全、Misc题型等&#xff0c;它们…

sonarqube 安装及使用

一、官网参考地址 相关版本下载地址 配置全局变量 .bash_profileexport SONAR_HOME=/Users/jd/soft/sonar-scanner-6.2.1.4610 export PATH=$PATH:$SONAR_HOME/bin export SQ_HOST=http://127.0.0.1:9000/ export SQ_TOKEN=squ_dbb1913e095a92a727a918a9ba6b1af94b007748二、…

使用ArcGIS/ArcGIS pro绘制六边形/三角形/菱形渔网图

在做一些尺度分析时&#xff0c;经常会涉及到对研究区构建不同尺度的渔网进行分析&#xff0c;渔网的形状通常为规则四边形。构建渔网的方法也很简单&#xff0c;使用ArcGIS/ArcGIS Pro工具箱中的【创建渔网/CreateFishnet】工具来构建。但如果想构建其他形状渔网进行相关分析&…

pytorch MoE(专家混合网络)的简单实现。

专家混合&#xff08;Mixture of Experts, MoE&#xff09;是一种深度学习模型架构&#xff0c;通常用于处理大规模数据和复杂任务。它通过将输入分配给多个专家网络&#xff08;即子模型&#xff09;&#xff0c;然后根据门控网络&#xff08;gating network&#xff09;的输出…

NAT 技术如何解决 IP 地址短缺问题?

NAT 技术如何解决 IP 地址短缺问题&#xff1f; 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 随着互联网的普及和发展&#xff0c;IP 地址的需求量迅速增加。尤其是 IPv4 地址&…

华为麦芒5(安卓6)termux记录 使用ddns-go,alist

下载0.119bate1版,不能换源,其他源似乎都用不了,如果root可以直接用面具模块 https://github.com/termux/termux-app/releases/download/v0.119.0-beta.1/termux-app_v0.119.0-beta.1apt-android-5-github-debug_arm64-v8a.apk 安装ssh(非必要) pkg install openssh开启ssh …

FPC在蓝牙耳机中有哪些应用?【新立电子】

随着科技的进步和消费者需求的提升&#xff0c;耳机已经从传统的有线连接转变为现在的无线蓝牙耳机&#xff0c;真正做到了便捷出行与极佳的用户体验。而FPC在蓝牙耳机中的应用主要体现在优化耳机的设计与性能上。 蓝牙耳机&#xff0c;主要使用方式是与手机、电脑等移动设备通…