前言
关系说明:PayService为支付接口,核心业务方法为epay(),该接口有好几个不同的实现类。
需求:在运行时需要动态决定走哪个实现类的逻辑。
解决方案
先上成品代码:
@Service
public class RouteService {
@Autowired
Set<PayService> payServiceSet;
Map<String, PayService> payServiceMap;
public PayResult epay(PayRequest payRequest) {
PayService payService = payServiceMap.get(payRequest.getChannelNo());
return payService.epay(payRequest);
}
@PostConstruct
public void init() {
for (PayService payService : payServiceSet) {
payServiceMap = new HashMap<>();
payServiceMap.put(payService.channel(), payService);
}
}
}
代码分析
使用Set<PayService>
类型会使Spring将所有实现了PayService
接口的类都注入进Set中。
@Autowired
Set<PayService> payServiceSet;
Map<String, PayService>
用于保存实现类与调用判断逻辑之间的映射关系。
Map<String, PayService> payServiceMap;
使用@PostConstruct
注解修饰的init方法会在Spring容器的启动时自动的执行,在其中完成映射Map的构建。
其中的payService的channel()
方法来自于接口定义,PayService接口要求每个实现类都实现该方法,该方法会返回不同实现类的唯一标识符。
@PostConstruct
public void init() {
for (PayService payService : payServiceSet) {
payServiceMap = new HashMap<>();
payServiceMap.put(payService.channel(), payService);
}
}
在调用时,请求参数中必须携带一个唯一标识符,用以表明本次调用需要走哪个实现类,也就是上述映射Map中的Key的值。
public PayResult epay(PayRequest payRequest) {
PayService payService = payServiceMap.get(payRequest.getChannelNo());
return payService.epay(payRequest);
}