当前位置: 首页 > backend >正文

Spring 策略模式实现

Spring 策略模式实现:工厂方法与自动注入详解

1. 背景介绍

在复杂的业务系统中,我们常常需要根据不同的场景选择不同的处理策略。本文将详细介绍在 Spring 框架中实现策略模式的两种主要方法。

2. 方案一: 手动注册工厂模式

2.1 定义工厂类

@Component
public class CalculateHandlerFactory implements InitializingBean, ApplicationContextAware {private ApplicationContext applicationContext;// 存储不同策略的映射private static final Map<String, CalculateHandler> HANDLER_MAP = new HashMap<>();// 初始化方法,自动注册所有处理器@Overridepublic void afterPropertiesSet() throws Exception {applicationContext.getBeansOfType(CalculateHandler.class).values().forEach(v -> HANDLER_MAP.putIfAbsent(v.getType(), v));}// 设置 ApplicationContext@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}// 根据类型获取对应的处理器public CalculateHandler getCalculateHandler(String calculateType) {return HANDLER_MAP.getOrDefault(calculateType, null);}
}

2.2 实现步骤

  1. 实现 InitializingBean 接口,在 Bean 初始化时自动注册处理器
  2. 实现 ApplicationContextAware 接口,获取 Spring 应用上下文
  3. 使用 Map 存储不同类型的处理器
  4. 提供根据类型获取处理器的方法

2.3 优点

  • 对注册过程有精细化控制
  • 可以添加自定义的注册逻辑
  • 灵活性高

3. 方案二: 自动注入策略模式

3.1 定义策略接口

public interface CalculateHandler {// 获取处理类型String getType();// 具体计算方法double calculate(double a, double b);
}

3.2 实现具体策略

@Component
public class AddCalculateHandler implements CalculateHandler {@Overridepublic String getType() {return "add";}@Overridepublic double calculate(double a, double b) {return a + b;}
}@Component
public class SubtractCalculateHandler implements CalculateHandler {@Overridepublic String getType() {return "subtract";}@Overridepublic double calculate(double a, double b) {return a - b;}
}

3.3 策略管理服务

@Service
public class CalculateService {@Autowiredprivate Map<String, CalculateHandler> calculateHandlerMap;public double calculate(String type, double a, double b) {CalculateHandler handler = calculateHandlerMap.get(type);if (handler == null) {throw new IllegalArgumentException("未找到对应的计算处理器");}return handler.calculate(a, b);}
}

3.4 工作原理详解

3.4.1 自动注册机制

当使用 @Autowired Map<String, Interface> 时,Spring 会:

  • 扫描所有实现指定接口的 Bean
  • 使用 Bean 名称作为 Map 的 Key
  • 使用 Bean 实例作为 Map 的 Value
3.4.2 Bean 名称规则
  • 默认使用类名首字母小写作为 Bean 名称
  • 可以通过 @Component("customName") 自定义 Bean 名称

4. 高级用法

4.1 按优先级排序

@Service
public class CalculateService {@Autowiredprivate Map<String, CalculateHandler> calculateHandlerMap;// 按照 @Order 注解排序@Autowiredprivate List<CalculateHandler> calculateHandlerList;
}

4.2 自定义 Key 获取

@Service
public class CalculateService {@Autowiredprivate Map<String, CalculateHandler> calculateHandlerMap;// 使用自定义方法获取 Keypublic double calculate(String type, double a, double b) {CalculateHandler handler = calculateHandlerMap.values().stream().filter(h -> h.getType().equals(type)).findFirst().orElseThrow(() -> new IllegalArgumentException("未找到处理器"));return handler.calculate(a, b);}
}

5. 两种方案对比

特性手动注册自动注入
代码复杂度较高较低
灵活性
初始化控制精细简单
性能略低略高

6. 优点和适用场景

6.1 优点

  1. 代码解耦
  2. 动态扩展
  3. 无需手动维护注册表
  4. 充分利用 Spring 依赖注入机制

6.2 适用场景

  • 策略模式
  • 插件化开发
  • 可插拔的业务处理器
  • 系统扩展性要求高的场景

7. 注意事项

  1. 保证 Bean 名称唯一性
  2. 接口设计要合理
  3. 做好异常处理
  4. 考虑性能和扩展性

8. 最佳实践

  1. 保持接口简洁明了
  2. 明确定义每个策略的职责
  3. 合理设计方法签名
  4. 添加必要的异常处理
  5. 考虑性能和扩展性

结论

通过 Spring 的依赖注入和自动装配机制,我们可以非常优雅地实现策略模式,使代码更加灵活、可读和可维护。选择合适的实现方式,需要根据具体的业务场景和系统架构来权衡。

http://www.xdnf.cn/news/16233.html

相关文章:

  • 【DeepRare】疾病识别召回率100%
  • SpringBoot学习路径二--Spring Boot自动配置原理深度解析
  • 教培机构如何开发自己的证件照拍照采集小程序
  • 萤石云替代产品摄像头方案萤石云不支持TCP本地连接-东方仙盟
  • 深入解析Hadoop MapReduce中Reduce阶段排序的必要性
  • 《Uniapp-Vue 3-TS 实战开发》自定义环形进度条组件
  • 人工智能冗余:大语言模型为何有时表现不佳(以及我们能做些什么)
  • 【js】ES2025新语法糖
  • 缓存HDC内容用于后续Direct2D绘制.
  • C#(基本语法)
  • SQLite中SQL的解析执行:Lemon与VDBE的作用解析
  • 机器学习笔记(三)——决策树、随机森林
  • 使用Python绘制金融数据可视化工具
  • 云原生可观测-日志观测(Loki)最佳实践
  • MinIO:云原生对象存储的终极指南
  • IT领域需要“落霞归雁”思维框架的好处
  • 互联网金融项目实战(大数据Hadoop hive)
  • 基于 Nginx 与未来之窗防火墙构建下一代自建动态网络防护体系​—仙盟创梦IDE
  • Hadoop 之 Yarn
  • AI与区块链融合:2025年的技术革命与投资机遇
  • 星图云开发者平台新功能速递 | 页面编辑器:全场景编辑器,提供系统全面的解决方案
  • Oracle数据块8KB、OS默认认块管理4KB,是否需调整大小为一致?
  • 大型微服务项目:听书——11 Redisson分布式布隆过滤器+Redisson分布式锁改造专辑详情接口
  • Java设计模式-建造者模式
  • 自动驾驶训练-tub详解
  • AUTO TECH 2025 华南展:汽车智能座舱的千亿市场,正被谁悄悄重塑?
  • 汽车功能安全 -- TC3xx Error Pin监控机制
  • Django集成Swagger全指南:两种实现方案详解
  • FastDFS如何提供HTTP访问电子影像文件
  • 《Nature》|scRNA Velocity剪切速率分析