通过反射读取@chargemode注解实现动态策略路由,将结算模式(如cash、coupon)与对应chargestrategy实现类绑定,启动时扫描缓存至concurrentmap,运行时o(1)查表调用,避免硬编码,提升可扩展性与健壮性。

在购物车多模式结算场景中,用反射读取类注解来动态路由到不同计费策略,核心是把“结算方式”和“策略实现类”通过注解绑定,再在运行时根据订单的结算类型(如 cash、coupon、points)自动找到并调用对应策略类。不依赖硬编码 if-else 或 switch,提升可扩展性。
定义统一策略接口与注解
先约定策略行为边界:
- 所有计费策略实现同一接口,比如
ChargeStrategy,含calculate(Order order)方法 - 自定义注解
@ChargeMode,标注在策略实现类上,指定它支持的结算模式标识(字符串)
示例注解定义:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ChargeMode {
String value(); // 如 "cash", "coupon"
}
为每个策略类打上注解
让每种计费逻辑自说明其适用模式:
@ChargeMode("cash")
public class CashChargeStrategy implements ChargeStrategy {
public BigDecimal calculate(Order order) { ... }
}
@ChargeMode("coupon")
public class CouponChargeStrategy implements ChargeStrategy {
public BigDecimal calculate(Order order) { ... }
}
@ChargeMode("points")
public class PointsChargeStrategy implements ChargeStrategy {
public BigDecimal calculate(Order order) { ... }
}
启动时扫描并缓存策略映射
应用初始化阶段(如 Spring 的 @PostConstruct 或静态块),用反射扫描指定包下所有带 @ChargeMode 的类:
- 用
ClassPathScanningCandidateComponentProvider(Spring)或Reflections库获取候选类 - 对每个类调用
clazz.getAnnotation(ChargeMode.class)读取 mode 值 - 将
mode → 策略实例存入ConcurrentMap<string chargestrategy></string>(注意:需确保单例,避免每次 new)
这样,后续结算时只需 strategyMap.get(order.getMode()).calculate(order) 即可完成路由。
注意事项与健壮性处理
- 注解值必须全局唯一,重复 mode 会导致后注册覆盖——可在扫描时校验并抛异常
- 策略类需有无参构造器,否则反射
newInstance()会失败(推荐用 Spring 容器托管并注入) - 订单 mode 字段为空或非法时,应 fallback 到默认策略(如抛
UnsupportedChargeModeException) - 避免在高频调用路径(如 calculate 方法内)反复反射——映射关系只构建一次,运行时纯查表











