基于Spring IOC实现动态简易版的SPI

基于Java自实现的SPI机制的缺陷,以及使用的复杂性,在实际项目中可以通过Spring IOC来简易的实现一版。
核心做法是:

  1. 利用ApplicationContext的getBeansOfType()方法来获取目标接口的全部实现类
  2. 需要调用接口的地方, 对外预留属性对应值为接口实现的实际bean_name, 然后根据上面的结果是一个Map, key为接口实现的bean_name, value为接口实现类, 然后通过预留属性获取用户想要使用的具体实现类,属性可以预留默认值,即为系统默认;用户可再进行实现,然后通过预留的属性,切换为自己的bean_name,即可完成实现的动态切换

举个例子:
现在有一个日志持久化的动作, 然后定义一个接口,内部提供两个实现,一个是持久化到db, 一个是持久化到mongo, 类图如下
在这里插入图片描述

提供一个配置类属性,核心如下

@Data
@ConfigurationProperties(prefix = "customs.mq-message-properties")
public class MqMessageProperties {

    /**
     * 落库监听日志的实现类的beanName
     * 默认使用Mongo落库,可切换为数据库
     * @see com.ddf.boot.common.mq.persistence.LogMqPersistenceProcessor
     */
    private String logMqPersistenceProcessorBeanName = "mongoLogMqPersistenceProcessor";
}

调用的地方可以使用如下方式

// 从Spring IOC中获取LogMqPersistenceProcessor接口的全部实现类
// SpringContextHolder这个是封装的静态类,其实就是实现了ApplicationContextAware接口,然后可以获取到ApplicationContext
Map<String, LogMqPersistenceProcessor> processorMap = SpringContextHolder.getBeansOfType(LogMqPersistenceProcessor.class);
// mqMessageProperties.getLogMqPersistenceProcessorBeanName即前面说到的预留的bean_name属性,通过这个属性来找到要使用的实现类
if (CollUtil.isNotEmpty(processorMap) && processorMap.containsKey(mqMessageProperties.getLogMqPersistenceProcessorBeanName())) {
	processorMap.get(mqMessageProperties.getLogMqPersistenceProcessorBeanName()).persistence(poll, logMqListener);
} else {
	log.warn("没有配置mq监听消费持久化方案");
}

如果用户想要切换持久化的目的地,只要修改上面的mqMessageProperties.getLogMqPersistenceProcessorBeanName这个配置类这个字段的属性即可,用户如果不满意已有的两种实现,可以再重新实现接口LogMqPersistenceProcessor, 持久化到Redis或者File随便,然后修改属性的bean_name指向自己的实现即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值