Spring boot 之动态的获取不同的实现类

目录
  1. 1. 定义接口,创建接口实现类
  2. 2. 方式一:利用 @Autowired 把多实现类注入到一个 Map
  3. 3. 方式二:利用 ApplicationContext

一个接口在不同场景,需要有不同的实现类,实现动态调用

定义接口,创建接口实现类

定义支付方式接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 支付方式接口
*/
public interface PaymentService {

/**
* 扫码支付
*
* @param transaction
* @return
* @throws Exception
*/
PublicResult tradePreCreate(Transaction transaction) throws Exception;
}

定义接口实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Service("WECHAT")
@Slf4j
public class WXPayService implements PaymentService {

@Override
public PublicResult tradePreCreate(Transaction transaction) throws Exception {
try {
// 处理业务逻辑
} catch (Exception e) {
log.error("微信 扫码支付失败:{}", e);
}
}
}

@Service("ALIPAY")
@Slf4j
public class AliPayService implements PaymentService {

@Override
public PublicResult tradePreCreate(Transaction transaction) throws Exception {
try {
// 处理业务逻辑
} catch (Exception e) {
log.error("支付宝扫码支付失败:{}", e);
}
}
}

方式一:利用 @Autowired 把多实现类注入到一个 Map

利用 @Autowired 注解,可以把同一接口的实现类,注入到集合类型中,比如 List,Map,这里使用 Map 介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Service
public class PaymentContext {

@Autowired
private Map<String, PaymentService> paymentMap = new ConcurrentHashMap<>();

/**
* 根据支付渠道获取对应实例
* @param payType (WECHAT 或者 ALIPAY)
* @return
*/
public PaymentService getPayment(String payType) {
return paymentMap.get(billType);
}

}

方式二:利用 ApplicationContext

通过实现ApplicationContextAware接口,获取ApplicationContext对象,再通过名称或类型去获取具体的实现

1
2
3
4
5
6
7
8
9
10
11
@Resource
private ApplicationContext applicationContext;

/**
* 根据支付渠道获取对应实例
* @param payType (WECHAT、ALIPAY)
* @return
*/
public PaymentService getInstance(String payType) {
return applicationContext.getBean(payType, PaymentService.class);
}

ApplicationObjectSupport类实现了ApplicationContextAwar 接口,或者通过ApplicationObjectSupport的getApplicationContext()方式获取到ApplicationContext对象。

1
2
3
4
5
6
7
8
9
10
11
public class PaymentContext extends ApplicationObjectSupport{

/**
* 根据支付渠道获取对应实例
* @param payType (WECHAT、ALIPAY)
* @return
*/
public PaymentService getInstance(String payType) {
return (PaymentService) getApplicationContext().getBean(payType);
}
}