Spring项目整合策略模式~实战应用
需求背景
1、在管控流程中,涉及到的业务操作很多,不同的业务具有不同的策略实现
举个具体的例子:
在比价管控流程中,有比价策略和管控策略,每个业务的比价和管控均不一样。因此使用策略模式来开发
整体架构流程
1、定义业务策略枚举: 比价 和 管控
/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:33**/
public enum StrategyType {priceCompare,priceControl;
}
2、定义业务策略注解,标注出 策略的类
/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:34**/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = ElementType.TYPE)
@Component
@Inherited
public @interface StrategyAnnotation {/*** 策略类型*/StrategyType[] strategyType();/*** 具体的策略建*/String[] dataType() default {};
}
3、定义策略基本方法
/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:46**/
public interface PriceCompareStrategy {/*** 执行价格比价*/public String doPriceCompare();
}/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:52**/
public interface PriceControlStrategy {/*** 执行管控* @return*/public String doPriceControl();
}
4、写每个具体实现的策略类
/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:44**/
@Service
@StrategyAnnotation(strategyType = StrategyType.priceCompare, dataType = "firstPriceCompare")
public class FirstPriceCompareStrategy implements PriceCompareStrategy {@Overridepublic String doPriceCompare() {System.out.println("-------first price compare start---------");System.out.println("-------do do do ---------");System.out.println("-------first price compare end---------");return "first price compare end";}
}/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:50**/
@Service
@StrategyAnnotation(strategyType = StrategyType.priceCompare, dataType = "secondPriceCompare")
public class SecondPriceCompareStrategy implements PriceCompareStrategy {@Overridepublic String doPriceCompare() {System.out.println("-------second price compare start---------");System.out.println("-------do do do ---------");System.out.println("-------second price compare end---------");return "second price compare end";}
}
/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:53**/
@Service
@StrategyAnnotation(strategyType = StrategyType.priceControl, dataType = "firstPriceControl")
public class FirstPriceControlStrategy implements PriceControlStrategy {@Overridepublic String doPriceControl() {System.out.println("---------do first price control start ---------------");System.out.println("---------do first price control end ---------------");return "do first price control end";}
}/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:53**/
@Service
@StrategyAnnotation(strategyType = StrategyType.priceControl, dataType = "secondPriceControl")
public class SecondPriceControlStrategy implements PriceControlStrategy {@Overridepublic String doPriceControl() {System.out.println("---------do second price control start ---------------");System.out.println("---------do second price control end ---------------");return "do second price control start";}
}@Service
@StrategyAnnotation(strategyType = {StrategyType.priceCompare, StrategyType.priceControl}, dataType = "commonStrategy")
public class PriceCompareAndControlStrategy implements PriceCompareStrategy, PriceControlStrategy {@Overridepublic String doPriceCompare() {System.out.println("-------common price compare start---------------");System.out.println("-------common price compare end---------------");return "common price compare end";}@Overridepublic String doPriceControl() {System.out.println("-------common price control start---------------");System.out.println("-------common price control end---------------");return "common price control end";}
}
5、编写策略管理类,管理所有的策略,并且对外暴露出 拿到具体策略类的方法
package com.dgut.strategy.springboot_strategy;import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;import javax.annotation.PostConstruct;
import java.util.Map;/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:59**/
@Service
public class StrategyServiceManager {@Autowiredprivate ApplicationContext context;/*** 存储策略:类型:具体实现类*/private Map<StrategyType, Map<String, Object>> map;public <E> E getStrategyInstance(StrategyType strategyType, String type, Class<E> eClass) {Map<String, Object> strategyTypeMap = map.get(strategyType);if (strategyTypeMap != null && !map.isEmpty()) {Object bean = strategyTypeMap.get(type);if (bean != null) {return eClass.cast(bean);}}return null;}@PostConstructprivate void init() {map = Maps.newHashMap();Map<String, Object> beans = context.getBeansWithAnnotation(StrategyAnnotation.class);for (Object value : beans.values()) {StrategyAnnotation annotation = value.getClass().getAnnotation(StrategyAnnotation.class);StrategyType[] strategyTypes = annotation.strategyType();String[] dataTypes = annotation.dataType();if (strategyTypes == null || strategyTypes.length == 0 || dataTypes == null || dataTypes.length == 0) {throw new RuntimeException("注解上必填字段不能为空");}for (StrategyType strategyType : strategyTypes) {for (String dataType : dataTypes) {map.computeIfAbsent(strategyType, k -> Maps.newHashMap()).put(dataType, value);}}}}}
6、代码流程测试
package com.dgut.strategy.springboot_strategy;import com.dgut.strategy.springboot_strategy.compare.PriceCompareStrategy;
import com.dgut.strategy.springboot_strategy.control.PriceControlStrategy;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;/*** @description:* @author: hongbin.zheng* @create: 2023-07-18 16:17**/
@SpringBootTest
public class StrategyTest {@Autowiredprivate StrategyServiceManager strategyServiceManager;@Testpublic void test2() {String strategyName = "priceControl";String dataType = "firstPriceControl";System.out.println(priceControlTest(strategyName, dataType));String dataType2 = "secondPriceControl";System.out.println(priceControlTest(strategyName, dataType2));String dataType3 = "commonStrategy";System.out.println(priceControlTest(strategyName, dataType3));}public String priceControlTest(String strategyName, String dataType) {StrategyType strategyType = StrategyType.valueOf(strategyName);if (strategyType == null) {return "管控策略不存在";}PriceControlStrategy strategyInstance = strategyServiceManager.getStrategyInstance(strategyType, dataType, PriceControlStrategy.class);if (strategyInstance == null) {return "找不到管控策略";}return strategyInstance.doPriceControl();}@Testpublic void test() {String strategyName = "priceCompare";String dataType = "firstPriceCompare";System.out.println(priceCompareTest(strategyName, dataType));String dataType2 = "secondPriceCompare";System.out.println(priceCompareTest(strategyName, dataType2));String dataType3 = "commonStrategy";System.out.println(priceCompareTest(strategyName, dataType3));}public String priceCompareTest(String strategyName, String dataType) {StrategyType strategyType = StrategyType.valueOf(strategyName);if (strategyType == null) {return "策略不存在";}PriceCompareStrategy strategyInstance = strategyServiceManager.getStrategyInstance(strategyType, dataType, PriceCompareStrategy.class);if (strategyInstance == null) {return "找不到比价策略";}return strategyInstance.doPriceCompare();}
}
技术细节
通过spring的context对象,解析获取类注解,拿到bean,常规操作,这个要学起来,很多地方可以这样子操作呢。
总结
知道的越多,不知道的越多,希望对你有帮助! \color{red}知道的越多,不知道的越多,希望对你有帮助! 知道的越多,不知道的越多,希望对你有帮助!
相关文章:
Spring项目整合策略模式~实战应用
需求背景 1、在管控流程中,涉及到的业务操作很多,不同的业务具有不同的策略实现 举个具体的例子: 在比价管控流程中,有比价策略和管控策略,每个业务的比价和管控均不一样。因此使用策略模式来开发 整体架构流程 1、…...
mybatis PageHelper的坑---记录
记录下,自己新开了一个kotlin的项目从而替换java项目,同时升级了部分组件,包括pageHelper,以往代码里有动态sql的配置 //通过不为null的属性查找数据 val tmpResult: List<Map<String?, Any?>> sqlSessionTemplat…...
uniapp微信小程序下载文件并打开
uni.downloadFile({url: 下载的地址,success(res) {console.log(res)if (res.statusCode 200) {console.log(下载成功);var filePath encodeURI(res.tempFilePath);uni.openDocument({filePath: filePath,fileType: "xlsx",showMenu: true,success: function(res) …...
安卓Intent打开系统进程汇总
1:拨打电话 val uri Uri.parse("tel:10086")val intent Intent(Intent.ACTION_DIAL,uri)startActivity(intent) 2:发送短信 val smsUri Uri.parse("smsto:10086")val intent1 Intent(Intent.ACTION_SENDTO,smsUri)intent1.putE…...
python学习(廖雪峰的官方网站部分,自学笔记)
python学习 廖雪峰的官方网站强烈推荐 字符串 Python提供了ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符 ord( )先当与把字符转成整形,chr( ) 把编码转化成相应的字符 有些时候,字符串里面的%是一个普通字符怎么办&…...
python题-检查该字符串的括号是否成对出现
给定一个字符串,里边可能包含“()”、"{}"两种括号,请编写程序检查该字符串的括号是否成对出现。 输出: true:代表括号成对出现并且嵌套正确,或字符串无括号字符。 false:未正确使用括号字符。 …...
3ds Max建模教程:模拟布料拖拽撕裂和用剑撕裂两种效果
推荐: NSDT场景编辑器 助你快速搭建可二次开发的3D应用场景 1. 拖拽撕布 步骤 1 打开 3ds Max。 打开 3ds Max 步骤 2 在透视视口中创建平面。保持其长度 后座和宽度后座为 100。 创建平面 步骤 3 转到助手>假人并在 飞机的两侧。 助手>假人 步骤 4 选…...
数据可视化(4)散点图及面积图
1.简单散点图 #散点图 #scatter(x,y) x数据,y数据 x[i for i in range(10)] y[random.randint(1,10) for i in range(10)] plt.scatter(x,y) plt.show()2.散点图分析 #分析广告支出与销售收入相关性 dfcarpd.read_excel(广告支出.xlsx) dfdatapd.read_excel(销售…...
Redis - 数据过期策略
Redis提供了两种数据过期策略 惰性删除 和 定期删除 惰性删除 当某个key过期时,不马上删除,而是在调用时,再判断它是否过期,如果过期再删除它 优点 : 对CPU友好,对于很多用不到的key,不用浪费…...
英文论文(sci)解读复现:基于YOLOv5的自然场景下苹果叶片病害实时检测
对于目标检测算法改进,但是应用于什么场景,需要什么改进方法对应与自己的应用场景有效果,并且多少改进点能发什么水平的文章,为解决大家的困惑,此系列文章旨在给大家解读发表高水平学术期刊中的SCI论文,并对…...
【Liux下6818开发板(ARM)】实现简易相册
(꒪ꇴ꒪ ),hello我是祐言博客主页:C语言基础,Linux基础,软件配置领域博主🌍快上🚘,一起学习!送给读者的一句鸡汤🤔:集中起来的意志可以击穿顽石!作者水平很有限,如果发现错误&#x…...
Kubernetes(K8s)从入门到精通系列之六:K8s的基本概念和术语之存储类
Kubernetes K8s从入门到精通系列之六:K8s的基本概念和术语之存储类 一、存储类二、emptyDir三、hostPath四、公有云Volume五、其他类型的Volume六、动态存储管理一、存储类 存储类的资源对象主要包括: VolumePersistent VolumePVCStorageClass基础的存储类资源对象——Volum…...
Spark-统一内存模型
总结: Spark的内存模型分为4部分,分别是存储内存,计算内存,其他内存,预留内存; 其中存储内存和计算内存可以动态占用,当己方内存不足对方空余则可占用对方的内存,计算内存被存储内…...
类的继承和super关键字的使用(JAVA)
继承 所有的OOP语言都会有三个特征: 封装(点击可跳转);继承;多态 为什么会有继承呢?可以先看下面的例子: 上面这两个类中的代码很相似因为它们只有最后一个方法不同其它的都相同,这样…...
BGP属性+选路规则
目录 一,BGP的属性—基础属性 1.PrefVal 2.LocPrf 3、优先本地下一跳 (NextHop) 4、AS-PATH 5、起源属性 6、MED -多出口鉴别属性 二,BGP选路规则 三,BGP的社团属性 一,BGP的属性—基础…...
类的实例化
类的实例化 class Date { public:void Init(int year, int month, int day){_year year;_month month;_day day;}private:int _year;int _month;int _day; //这只是函数的一个声明并没有定义 };上面是一个类,我们可以把有花括号括起来的叫做一个域ÿ…...
智能提词器有哪些?了解一下这款提词工具
智能提词器有哪些?使用智能提词器可以帮助你更好地准备和交付演讲、报告或其他提词场合。它可以提高你的效率,节省你的时间,并让你更加自信地与听众沟通。另外,智能提词器还可以提供一些有用的功能,如语音识别、智能建…...
oracle 19c rac环境配置firewalld
rac环境ip地址说明 [rootdb1 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 172.16.100.19 db1 172.16.100.30 …...
Flutter 之Bloc入门指南实现倒计时功能
Flutter Timer By Bloc 前言Stream.periodic实现倒计时定义Bloc状态定义Bloc事件定义Bloc组件定义View层参考资料前言 使用Bloc开发Flutter的项目,其项目结构都很简单明确,需要创建状态,创建事件,创建bloc,创建对应的View。flutter_timer项目来分析下Bloc的使用方法。 通…...
目标识别数据集互相转换——xml、txt、json数据格式互转
VOC数据格式与YOLO数据格式互转 1.VOC数据格式 VOC(Visual Object Classes)是一个常用的计算机视觉数据集,它主要用于对象检测、分类和分割任务。VOC的标注格式,也被许多其他的数据集采用,因此理解这个数据格式是很重…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...
认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...
