策略模式是一种行为设计模式,它允许在运行时选择算法的行为。在Spring框架中,我们可以利用@Resource
注解和Map
集合来优雅地实现策略模式。
在Spring框架中,当你使用@Resource
注解注入一个Map
时,Spring会自动将所有类型为T的bean收集到这个Map中,其中:
Spring框架对集合类型的依赖注入有特殊处理:
@Resource
注解默认按名称装配,但当目标是一个Map时,Spring会特殊处理:
Spring在依赖注入时的处理流程:
我们直接定义一个Controller,并且在Controller中使用@Resource
和Map
@RestController
@RequestMapping("/test")
public class TestController {
@Resource
private Map<String, Object> beanMap = new ConcurrentHashMap<>();
public void beanMap() {
System.out.println(beanMap.size());
}
}
在实际的开发中,我们希望Map中只是存储需要的Bean,并且Controller中可以根据beanName进行转发到不同的Service中,步骤如下:
public interface PaymentStrategy {
void pay();
}
@Service("ALI")
@Slf4j
public class AliStrategyService implements PaymentStrategy {
@Override
public void pay() {
log.info("使用支付宝支付");
}
}
@Service("WX")
@Slf4j
public class WxStrategyService implements PaymentStrategy {
@Override
public void pay() {
log.info("使用微信支付");
}
}
@RestController
@RequestMapping("/test")
public class TestController {
@Resource
private Map<String, PaymentStrategy> beanMap = new ConcurrentHashMap<>();
public void beanMap() {
PaymentStrategy wx = beanMap.get("WX");
wx.pay();
PaymentStrategy ali = beanMap.get("ALI");
ali.pay();
}
}
可以看到map中,就只有两个Bean,并且key就是我们通过@Service(value)定义的名称
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface PaymentType {
String value();
}
@Service(value)
替换为@PaymentType (value)
,比如:@PaymentType("CARD")
@Slf4j
public class CardStrategyService implements PaymentStrategy {
@Override
public void pay() {
log.info("使用银行卡支付");
}
}
当前的Service
使用了策略模式