基于 Spring 的策略模式框架,用于根据不同的类的标识获取对应的处理器实例

基于 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) 定义所有策略类的统一方法(规范策略的行为) 自定义接口(如 PayStrategyOrderHandler
策略实现类(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. 工作流程
  1. Spring 容器启动,加载所有 bean 定义
  2. RegisterHandleContext 作为 BeanFactoryPostProcessor 被调用
  3. 扫描指定包下的类,收集带有 @BeforeApproveHandler 注解的处理器类
  4. 创建 FlowHandleContext 并注册到 Spring 容器
  5. 当需要处理某个流程时,调用 FlowHandleContext.getHandle(processKey) 获取对应处理器
  6. 使用获取到的处理器实例执行具体的处理逻辑

方式二: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]
    }
}
相关推荐
王道长服务器 | 亚马逊云2 小时前
一个迁移案例:从传统 IDC 到 AWS 的真实对比
java·spring boot·git·云计算·github·dubbo·aws
华仔啊2 小时前
为什么 keySet() 是 HashMap 遍历的雷区?90% 的人踩过
java·后端
9号达人2 小时前
Java 13 新特性详解与实践
java·后端·面试
橙序员小站2 小时前
搞定系统设计题:如何设计一个支付系统?
java·后端·面试
Java水解2 小时前
Spring Security6.3.x使用指南
后端·spring
嘟嘟可在哪里。2 小时前
IntelliJ IDEA git凭据帮助程序
java·git·intellij-idea
岁忧2 小时前
(LeetCode 每日一题) 3541. 找到频率最高的元音和辅音 (哈希表)
java·c++·算法·leetcode·go·散列表
_extraordinary_2 小时前
Java 多线程进阶(四)-- 锁策略,CAS,synchronized的原理,JUC当中常见的类
java·开发语言
纪元A梦3 小时前
贪心算法应用:信用评分分箱问题详解
java·算法·贪心算法