基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例
### 文章目录
- [基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [@[toc]](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [一、策略模式的核心角色(Spring 中对应实现)](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [二、实现方式](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [方式一:`Spring 自动扫描并组装所有策略实现类到 Map中`](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [1. 核心注册类实现BeanFactoryPostProcessor](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [2. BeforeApproveHandler 注解](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [3. 业务BeforeApproveHandleService 接口](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [4. 具体业务处理器实现类(以第一个为例)](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [5. 具体业务处理器实现类(以第二个为例)](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [6. 具体业务处理器实现类(以第三个为例)](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [7. 策略上下文(管理和选择策略)](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [8. 客户端使用](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [9. 工作流程](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [方式二:`Spring 自动扫描并组装所有策略实现类到 List 中`](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [1. 定义策略接口](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [2. 实现具体策略类](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [3. 策略上下文(注入 List <策略接口>)](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [4. 使用策略模式](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果) - [5. 测试效果](#文章目录 基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例 @[toc] 一、策略模式的核心角色(Spring 中对应实现) 二、实现方式 方式一:
Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor 2. BeforeApproveHandler 注解 3. 业务BeforeApproveHandleService 接口 4. 具体业务处理器实现类(以第一个为例) 5. 具体业务处理器实现类(以第二个为例) 6. 具体业务处理器实现类(以第三个为例) 7. 策略上下文(管理和选择策略) 8. 客户端使用 9. 工作流程 方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口 2. 实现具体策略类 3. 策略上下文(注入 List <策略接口>) 4. 使用策略模式 5. 测试效果)
比方说我们有一个支付方式业务功能,这个支付功能里面有多种不同支付方式的场景的需求,如微信支付、支付宝、银联......等支付方式但是这些支付方式都需要走一样的,申请,审批......等过程,只是业务逻辑不同而已,那么我们就可以定义一个接口,用不同的实现类来实现这个接口,通过不同的业务走不同的实现,那么我们就可以使用策略模式解决,而不用写一堆 if---else
。
一、策略模式的核心角色(Spring 中对应实现)
首先明确策略模式的 3 个核心角色,以及在 Spring 中如何落地:
策略模式角色 | 作用说明 | Spring 中常见实现形式 |
---|---|---|
策略接口(Strategy) | 定义所有策略类的统一方法(规范策略的行为) | 自定义接口(如 PayStrategy 、OrderHandler ) |
策略实现类(ConcreteStrategy) | 实现策略接口,提供具体的业务逻辑(如 "支付宝支付""微信支付") | 标注 @Component 的 Spring Bean |
策略上下文(Context) | 持有策略接口的引用,负责动态选择 / 注入具体策略,并对外提供调用入口 | 注入策略集合(如 Map<策略标识, 策略接口> ) |
二、实现方式
方式一:Spring 自动扫描并组装所有策略实现类到 Map中
1. 核心注册类实现BeanFactoryPostProcessor
实现
BeanFactoryPostProcessor
接口,在 Spring 容器加载完所有 Bean 定义(但未实例化任何 Bean 之前),主动扫描并收集策略类,构建策略标识与策略类的映射关系,再将这个映射关系注册到 Spring 容器中,供后续动态获取策略实例。
java
// 引入Lombok的@Slf4j注解,自动生成日志对象
@Slf4j
// 标记为Spring组件,使其被Spring容器管理
@Component
// 实现BeanFactoryPostProcessor接口,在bean实例化前处理bean定义
public class RegisterHandleContext implements BeanFactoryPostProcessor {
// 定义要扫描的包路径
private static final String SCAN_PACKGE = "com.hy.material.flow";
// 实现接口方法,在bean工厂处理完成后执行
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 创建Map存储"流程标识-处理器类"的映射(前置审批处理器)
Map<String, Class> beforeApproveService = new HashMap<>();
// 这个Map在当前代码中未使用,可能是预留扩展
Map<String, Class> processNodeCodeService = new HashMap<>();
// 扫描指定包下的所有类,并对每个类进行处理
ClassScanner.scanPackage(SCAN_PACKGE).forEach(clazz -> {
// 检查类上是否有@BeforeApproveHandler注解
BeforeApproveHandler beforeApproveHandler = clazz.getAnnotation(BeforeApproveHandler.class);
// 如果有该注解
if (beforeApproveHandler != null) {
// 将注解的值(流程标识)作为key,类本身作为value存入Map
beforeApproveService.put(beforeApproveHandler.value(), clazz);
}
});
// 创建FlowHandleContext实例,传入处理器映射关系
FlowHandleContext flowHandleContext = new FlowHandleContext(beforeApproveService);
// 将FlowHandleContext实例注册为Spring单例bean,bean名称为类的全限定名
beanFactory.registerSingleton(FlowHandleContext.class.getName(), flowHandleContext);
}
}
2. BeforeApproveHandler 注解
java
// 注解作用目标:类/接口
@Target({ElementType.TYPE})
// 注解保留策略:运行时保留(可以通过反射获取)
@Retention(RetentionPolicy.RUNTIME)
// 自定义注解,用于标记前置审批处理器
public @interface BeforeApproveHandler {
// 注解属性,存储流程标识,默认值为空字符串
String value() default "";
}
3. 业务BeforeApproveHandleService 接口
java
// 前置审批处理器的接口,定义了处理器的标准
public interface BeforeApproveHandleService {
// 统一方法:处理支付
String pay(double amount);
}
4. 具体业务处理器实现类(以第一个为例)
java
// 引入Lombok的@Slf4j注解,自动生成日志对象
@Slf4j
// 标记为Spring服务类,注册为bean
@Service
// Lombok注解,自动生成全参构造方法
@AllArgsConstructor
// 标记为前置审批处理器,指定对应的支付宝支付,FlowConstants是自定义的枚举类
@BeforeApproveHandler(FlowConstants.alipay)
// 实现前置审批处理器接口
public class GylAllocateApplyApproveHandleExecute implements BeforeApproveHandleService {
@Override
public String pay(double amount) {
return "支付宝支付成功,金额:" + amount;
}
}
5. 具体业务处理器实现类(以第二个为例)
java
@Slf4j
@Service
@AllArgsConstructor
@BeforeApproveHandler(FlowConstants.wechatPay)
public class GylAllocateApplyOrderApproveHandleExecute implements BeforeApproveHandleService {
@Override
public String pay(double amount) {
return "微信支付成功,金额:" + amount;
}
}
6. 具体业务处理器实现类(以第三个为例)
java
@Slf4j
@Service
@AllArgsConstructor
@BeforeApproveHandler(FlowConstants.wangyin)
public class GylAllocateReceiptHandleExecute implements BeforeApproveHandleService {
@Override
public String pay(double amount) {
return "网银支付成功,金额:" + amount;
}
}
7. 策略上下文(管理和选择策略)
java
// 引入Lombok的@Slf4j注解,自动生成日志对象
@Slf4j
// 处理器上下文类,用于管理和获取处理器
public class FlowHandleContext {
// 存储"流程标识-处理器类"的映射关系
private Map<String, Class> flowService;
// 构造方法,初始化映射关系
public FlowHandleContext(Map<String, Class> flowService) {
this.flowService = flowService;
}
// 根据流程标识获取对应的处理器实例
public BeforeApproveHandleService getHandle(String processKey) {
try {
// 根据processKey获取对应的枚举值
ProcessKeyEnum processKeyEnum = ProcessKeyEnum.getByProcessKey(processKey);
// 获取Spring应用上下文
ApplicationContext applicationContext = SpringContextHolder.getApplicationContext();
// 从映射中获取处理器类,如果找不到则使用默认的支付标识对应的处理器
// 然后从Spring容器中获取该类的实例并返回
return (BeforeApproveHandleService) applicationContext.getBean(
flowService.getOrDefault(processKey, flowService.get(processKeyEnum.DEFAULT.getProcessKey())));
} catch (Exception e) {
// 记录错误日志
log.error(String.format("Cannot find class [%s] in ProcessKeyEnum[%s].", flowService.toString(), processKey), e);
}
// 如果获取失败,抛出异常
throw new CheckedException("不存在对应的支付");
}
}
8. 客户端使用
java
@SpringBootTest
public class PaymentTest {
@Autowired
private FlowHandleContext flowHandleContext;
@Test
public void testPay() {
// 1. 选择支付宝支付(传入策略的Bean名称)
String result1 = paymentContext.getHandle("alipay");
System.out.println(result1); // 输出:支付宝支付成功
// 2. 选择微信支付
String result2 = paymentContext.getHandle("wechatPay");
System.out.println(result2); // 输出:微信支付成功
}
}
这样我们通过代码实现了一个基于 Spring 的策略模式框架,用于根据不同的流程标识(processKey)获取对应的处理器实例
9. 工作流程
- Spring 容器启动,加载所有 bean 定义
RegisterHandleContext
作为BeanFactoryPostProcessor
被调用- 扫描指定包下的类,收集带有
@BeforeApproveHandler
注解的处理器类 - 创建
FlowHandleContext
并注册到 Spring 容器 - 当需要处理某个流程时,调用
FlowHandleContext.getHandle(processKey)
获取对应处理器 - 使用获取到的处理器实例执行具体的处理逻辑
方式二:Spring 自动扫描并组装所有策略实现类到 List 中
1. 定义策略接口
首先创建一个策略接口,声明所有策略需要实现的方法(包括一个用于标识策略的方法,方便后续匹配):
java
// 策略接口
public interface PaymentStrategy {
// 策略标识:返回当前支付方式的类型(如"alipay"、"wechat")
String getPaymentType();
// 核心业务方法:处理支付
String pay(BigDecimal amount);
}
2. 实现具体策略类
创建多个实现类,每个类对应一种具体策略,并使用 @Component
注解注册为 Spring Bean:
java
// 支付宝支付策略
@Component
public class AlipayStrategy implements PaymentStrategy {
@Override
public String getPaymentType() {
return "alipay"; // 策略标识
}
@Override
public String pay(BigDecimal amount) {
return "支付宝支付成功,金额:" + amount.toPlainString();
}
}
// 微信支付策略
@Component
public class WechatPaymentStrategy implements PaymentStrategy {
@Override
public String getPaymentType() {
return "wechat"; // 策略标识
}
@Override
public String pay(BigDecimal amount) {
return "微信支付成功,金额:" + amount.toPlainString();
}
}
// 银联支付策略
@Component
public class UnionPayStrategy implements PaymentStrategy {
@Override
public String getPaymentType() {
return "unionpay"; // 策略标识
}
@Override
public String pay(BigDecimal amount) {
return "银联支付成功,金额:" + amount.toPlainString();
}
}
3. 策略上下文(注入 List <策略接口>)
创建策略上下文类,通过构造器注入
List<PaymentStrategy>
,Spring 会自动将所有实现了该接口的 Bean 收集到这个 List 中
。上下文类负责根据条件匹配具体策略:
java
// 策略上下文
@Component
public class PaymentContext {
// Spring 自动注入:所有 PaymentStrategy 实现类的实例会被收集到 List 中
private final List<PaymentStrategy> paymentStrategies;
// 构造器注入(推荐,确保依赖不可变)
public PaymentContext(List<PaymentStrategy> paymentStrategies) {
this.paymentStrategies = paymentStrategies;
}
// 核心方法:根据支付类型匹配并执行对应的策略
public String executePayment(String paymentType, BigDecimal amount) {
// 遍历 List 匹配策略标识
PaymentStrategy strategy = paymentStrategies.stream()
.filter(s -> s.getPaymentType().equals(paymentType))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("不支持的支付方式:" + paymentType));
// 执行策略
return strategy.pay(amount);
}
// 扩展:获取所有支持的支付方式
public List<String> getAllSupportedPaymentTypes() {
return paymentStrategies.stream()
.map(PaymentStrategy::getPaymentType)
.collect(Collectors.toList());
}
}
4. 使用策略模式
在业务代码中注入 PaymentContext
,直接调用即可:
java
@Service
public class OrderService {
private final PaymentContext paymentContext;
@Autowired
public OrderService(PaymentContext paymentContext) {
this.paymentContext = paymentContext;
}
public String processPayment(String paymentType, BigDecimal amount) {
// 调用上下文执行支付(自动匹配策略)
return paymentContext.executePayment(paymentType, amount);
}
public List<String> getSupportedPayments() {
// 获取所有支持的支付方式
return paymentContext.getAllSupportedPaymentTypes();
}
}
5. 测试效果
java
@SpringBootTest
public class PaymentTest {
@Autowired
private OrderService orderService;
@Test
public void testPayment() {
// 测试微信支付
String result1 = orderService.processPayment("wechat", new BigDecimal("100"));
System.out.println(result1); // 输出:微信支付成功,金额:100
// 测试支付宝支付
String result2 = orderService.processPayment("alipay", new BigDecimal("200"));
System.out.println(result2); // 输出:支付宝支付成功,金额:200
// 查看所有支持的支付方式
List<String> types = orderService.getSupportedPayments();
System.out.println(types); // 输出:[alipay, wechat, unionpay]
}
}