【quarkus系列】实战自定义注解实现策略模式分发

2024-06-06 07:20

本文主要是介绍【quarkus系列】实战自定义注解实现策略模式分发,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 序言
  • 自定义注解
  • 业务接口
  • 渠道消息实现
  • 策略分发
  • 测试
  • 知识扩展
    • @Any
    • AnnotationLiteral 应用场景和语法

序言

策略模式大家都应该了解或者使用过,此篇文章中就不再阐述,之前springboot项目中小编也真正的实战应用过。现在换Quarkus框架开发项目,为了后期的项目业务的可扩展以及高可用,就构思并了解如何在Quarkus中使用,软件设计思想最重要,换组件无非换种语法而已,但是也需要摸索,排坑之类,下面给出一个简单的示例demo:模拟向不同的平台类型发送消息

自定义注解

基于Quarkus自定义注解的语法格式,与java语法基本一致,毕竟遵循 MicroProfile 和 Jakarta EE 的规范。

  • 核心代码
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
public @interface Platform {PlatformTypeEnum type();
}
  • 平台类型枚举
@AllArgsConstructor
@Getter
public enum PlatformTypeEnum {//企微WEWORK(1, "企微"),//小红书RED_BOOK(2, "小红书"),;private final Integer type;private final String desc;
}

业务接口

抽象消息业务接口,应用于多平台渠道实现

public interface MessageService {String sendMsg(String msg);}

渠道消息实现

  • 企业微信渠道实现
@Platform(type = PlatformTypeEnum.WEWORK)
@Dependent
public class WeWorkMessage implements MessageService {@InjectMessageRepo messageRepo;@Overridepublic String sendMsg(String msg) {//TODOreturn messageRepo.getMessage() + ", weWork";}
}
  • 小红书渠道消息实现
@Platform(type = PlatformTypeEnum.RED_BOOK)
@Dependent
public class RedBookMessage implements MessageService {@Overridepublic String sendMsg(String msg) {//TODOreturn "redBook";}
}

策略分发

  • 方式一:switch-case
  public MessageService getStrategy(PlatformTypeEnum platform) {switch (platform) {case WEWORK:return messageServices.select(WeWorkMessage.class).get();case RED_BOOK:return messageServices.select(RedBookMessage.class).get();default:return null;}}

这种方式违反了开闭原则,每次增加子类都需要修改此处的代码;

  • 方式二:动态分发
@ApplicationScoped
public class MessageStrategy {@Inject@AnyInstance<MessageService> messageServices;public MessageService getStrategy(PlatformTypeEnum platform) {return messageServices.select(new PlatformLiteral(platform)).get();}private static class PlatformLiteral extends AnnotationLiteral<Platform> implements Platform {private final PlatformTypeEnum platform;public PlatformLiteral(PlatformTypeEnum platform) {this.platform = platform;}@Overridepublic PlatformTypeEnum type() {return platform;}}
}

getStrategy 方法使用 messageServices.select 方法来动态选择符合条件的 MessageService 实例。
PlatformLiteral 用于在运行时创建一个带有具体值的 @Platform 注解。
PlatformLiteral 类扩展了 AnnotationLiteral 并实现了 Platform 接口。它接受一个 PlatformTypeEnum 值并重写 type 方法返回该值。通过这种方式,PlatformLiteral 在运行时创建了一个带有特定 PlatformTypeEnum 值的 @Platform 注解实例。

  • 优点
    这个机制允许在运行时动态选择不同的 MessageService 实现,而无需在编译时确定具体的实现类。

测试

@Path("/message")
@Tag(name = "消息")
public class MessageController {@InjectMessageStrategy messageStrategy;@Path("/get-msg")@GETpublic Response<String> getMsg(@QueryParam("platform") PlatformTypeEnum platform) {String test = messageStrategy.getStrategy(platform).sendMsg("test");return Response.ok(test);}
}

可以看到messageService中存在两个实现类
在这里插入图片描述
使用swagger测试,分布使用企微、小红书入参得到的结果如图:
在这里插入图片描述

  • 小红书,消息渠道分发
    在这里插入图片描述

知识扩展

基于方式二实现扩展使用的注解语法以及相关原理

@Any

  • 应用场景
    @Any 注解在 CDI(Context and Dependency Injection)中用于注入所有符合特定类型的 Bean 实例,而不考虑其他限定符。它通常用于动态选择或处理多个实现。

  • 语法

@Inject
@Any
Instance<SomeType> someInstances;
  • 原理
    @Any 告诉 CDI 容器注入所有符合类型 SomeType 的 Bean 实例,即使这些实例有其他限定符。

  • @Any注解的源码,是不是很熟悉呀

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@Documented
public @interface Any {public static final class Literal extends AnnotationLiteral<Any> implements Any {public static final Literal INSTANCE = new Literal();private static final long serialVersionUID = 1L;public Literal() {}}
}

AnnotationLiteral 应用场景和语法

  • 应用场景
    AnnotationLiteral 用于在运行时动态创建注解实例。它通常用于 CDI 的动态选择,特别是当需要根据条件在运行时选择特定 Bean 实例时。

  • 语法

public class SomeAnnotationLiteral extends AnnotationLiteral<SomeAnnotation> implements SomeAnnotation {private final SomeType value;public SomeAnnotationLiteral(SomeType value) {this.value = value;}@Overridepublic SomeType value() {return value;}
}
  • 原理
    AnnotationLiteral 是一个抽象类,用于表示注解的具体实例,提供了注解的具体实现,使得可以在运行时生成注解实例,用于 CDI 的选择操作。原理是利用泛型和反射机制,它通过创建一个匿名内部类来实现对注解实例的动态创建,通过扩展 AnnotationLiteral 类并实现注解接口的方法,可以动态创建带有具体值的注解实例,而不是依赖于编译时注解处理器生成的实例。

这篇关于【quarkus系列】实战自定义注解实现策略模式分发的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1035448

相关文章

Python实现终端清屏的几种方式详解

《Python实现终端清屏的几种方式详解》在使用Python进行终端交互式编程时,我们经常需要清空当前终端屏幕的内容,本文为大家整理了几种常见的实现方法,有需要的小伙伴可以参考下... 目录方法一:使用 `os` 模块调用系统命令方法二:使用 `subprocess` 模块执行命令方法三:打印多个换行符模拟

SpringBoot+EasyPOI轻松实现Excel和Word导出PDF

《SpringBoot+EasyPOI轻松实现Excel和Word导出PDF》在企业级开发中,将Excel和Word文档导出为PDF是常见需求,本文将结合​​EasyPOI和​​Aspose系列工具实... 目录一、环境准备与依赖配置1.1 方案选型1.2 依赖配置(商业库方案)二、Excel 导出 PDF

Python实现MQTT通信的示例代码

《Python实现MQTT通信的示例代码》本文主要介绍了Python实现MQTT通信的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 安装paho-mqtt库‌2. 搭建MQTT代理服务器(Broker)‌‌3. pytho

spring中的@MapperScan注解属性解析

《spring中的@MapperScan注解属性解析》@MapperScan是Spring集成MyBatis时自动扫描Mapper接口的注解,简化配置并支持多数据源,通过属性控制扫描路径和过滤条件,利... 目录一、核心功能与作用二、注解属性解析三、底层实现原理四、使用场景与最佳实践五、注意事项与常见问题六

使用zip4j实现Java中的ZIP文件加密压缩的操作方法

《使用zip4j实现Java中的ZIP文件加密压缩的操作方法》本文介绍如何通过Maven集成zip4j1.3.2库创建带密码保护的ZIP文件,涵盖依赖配置、代码示例及加密原理,确保数据安全性,感兴趣的... 目录1. zip4j库介绍和版本1.1 zip4j库概述1.2 zip4j的版本演变1.3 zip4

从入门到进阶讲解Python自动化Playwright实战指南

《从入门到进阶讲解Python自动化Playwright实战指南》Playwright是针对Python语言的纯自动化工具,它可以通过单个API自动执行Chromium,Firefox和WebKit... 目录Playwright 简介核心优势安装步骤观点与案例结合Playwright 核心功能从零开始学习

python生成随机唯一id的几种实现方法

《python生成随机唯一id的几种实现方法》在Python中生成随机唯一ID有多种方法,根据不同的需求场景可以选择最适合的方案,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习... 目录方法 1:使用 UUID 模块(推荐)方法 2:使用 Secrets 模块(安全敏感场景)方法

Java docx4j高效处理Word文档的实战指南

《Javadocx4j高效处理Word文档的实战指南》对于需要在Java应用程序中生成、修改或处理Word文档的开发者来说,docx4j是一个强大而专业的选择,下面我们就来看看docx4j的具体使用... 目录引言一、环境准备与基础配置1.1 Maven依赖配置1.2 初始化测试类二、增强版文档操作示例2.

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建