首先,定义接口或抽象父类。例如,定义一个Strategy接口,里面有execute方法。然后不同的策略类实现这个接口,比如ConcreteStrategyA、ConcreteStrategyB等,每个类用@Component注解,可能指定Bean的名字,或者用默认的类名首字母小写作为Bean名称。
然后,需要将这些Bean自动注入到一个Map中。Spring支持将同一类型的Bean注入到Map中,其中键是Bean的名称,值是对应的实例。例如,在某个服务类中,使用@Autowired private Map<String, Strategy> strategies; 这样,Spring会自动将所有的Strategy实现类放入这个Map,键是Bean的名称。
接下来,当需要执行某个策略时,根据传入的key(即Bean的名称)从Map中获取对应的实例,调用其execute方法。例如,在服务类中有一个方法,接收策略名称作为参数,然后调用strategies.get(name).execute()。
在Spring框架中,使用策略模式并结合依赖注入可以通过以下步骤实现将子类实例存入Map,并通过指定名称执行对应方法:
1. 定义策略接口或抽象类
public interface PaymentStrategy {
void processPayment(double amount);
}
2. 实现具体策略类(子类)
使用@Component
并为每个策略指定唯一的Bean名称:
@Component("creditCard")
public class CreditCardPayment implements PaymentStrategy {
@Override
public void processPayment(double amount) {
System.out.println("使用信用卡支付:" + amount);
}
}
@Component("alipay")
public class AlipayPayment implements PaymentStrategy {
@Override
public void processPayment(double amount) {
System.out.println("使用支付宝支付:" + amount);
}
}
3. 注入策略Map并执行
@Service
public class PaymentService {
private final Map<String, PaymentStrategy> strategies;
// 通过构造器注入,Key为Bean名称,Value为实例
@Autowired
public PaymentService(Map<String, PaymentStrategy> strategyMap) {
this.strategies = strategyMap;
}
public void executePayment(String method, double amount) {
PaymentStrategy strategy = strategies.get(method);
if (strategy == null) {
throw new IllegalArgumentException("无此支付方式: " + method);
}
strategy.processPayment(amount);
}
}
4. 使用示例
@RestController
public class PaymentController {
@Autowired
private PaymentService paymentService;
@PostMapping("/pay")
public String pay(@RequestParam String method, @RequestParam double amount) {
paymentService.executePayment(method, amount);
return "支付成功";
}
}
关键点说明
- 自动注入Map:Spring会自动将相同类型(
PaymentStrategy
)的Bean注入到Map中,Key为Bean名称,Value为实例。 - 策略扩展:新增支付方式只需添加实现类并用
@Component("新名称")
标记,无需修改其他代码。 - 异常处理:当传入不存在的Key时,需处理策略未找到的情况(如抛出异常或返回默认策略)。
自定义Map键名(可选)
若需使用非Bean名称的Key,可通过自定义注解实现:
定义注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface PaymentType {
String value();
}
应用注解到策略类:
@Component
@PaymentType("credit")
public class CreditCardPayment implements PaymentStrategy { ... }
手动构建策略Map:
@Service
public class PaymentService {
private final Map<String, PaymentStrategy> strategies = new HashMap<>();
@Autowired
public PaymentService(List<PaymentStrategy> strategyList) {
for (PaymentStrategy strategy : strategyList) {
PaymentType annotation = strategy.getClass().getAnnotation(PaymentType.class);
if (annotation != null) {
strategies.put(annotation.value(), strategy);
}
}
}
// 其他代码不变
}
这种方法允许更灵活地定义策略名称,同时保持代码的可扩展性。
@sercice(“queryability”)
public class QueryAbilityService implement Strategy{…}
private Map<String, Strategy> strategy;
strategy.get(“key”).ifPresent(handler->handler.onmessage(input));