spi机制适配多环境

场景:

1.我正在写一个框架,我想同时兼容spring环境、solon环境或者其他等等。同时还支持用户自定义或者进行覆盖。

像这种场景,一般使用spi结合优先级加载以及插件式进行加载,简单来说,举个简单例子:

用户a,spring项目,只需要引入我的 my-spring依赖,solon项目引入my-solon依赖

其他不支持的项目,引入my-core依赖,进行自实现

又或者用户spring环境,不想用框架内部的,用户可以自实现一个优先级更高的进行覆盖。

  1. my-core,定义spi接口,优先级最低为2,并进行默认空实现或其他实现

2.my-spring,定义spring的实现,优先级为1

3.my-solon,定义solon的实现,优先级为1

核心代码:

1.my-core:

1.1 顶层接口,定义加载的优先级方法

java 复制代码
/**
 * Spi实现的优先级接口 数字越小优先级越高
 */
public interface SpiPriority {

	int priority(); //优先级

}

1.2 业务接口继承

java 复制代码
/**
 * 环境加载接口
 *
 */
public interface Init extends SpiPriority {

	void envInit(Object obj); //加载环境

}

1.3 空实现

java 复制代码
/**
 * 环境加载local接口
 *
 */
public class LocalInit implements Init{

	void envInit(Object obj){ throw new RuntimeException("找不到具体实现类,请自实现或根据项目环境引入依赖")} 

    int priority(){return 2;}

}

1.4 spi配置

MATE_INF/services新建文件名为Init的全路径名,内容为localInit的全路径名

2.my-spring

实现Init接口,并配置spi配置

3.加载时机

一般在项目启动的时候进行加载

如spring环境,实现SmartInitializingSingleton,在单例bean全部实例化后执行

java 复制代码
        if (ObjectUtil.isNull(init)) {
			List<Init> list = new ArrayList<>();
			ServiceLoader.load(Init.class).forEach(list::add);
			list.sort(Comparator.comparingInt(Init::priority));
			init= list.get(0);
		}
		return init;

4.用户自实现或覆盖g

如spring环境 调整优先级即可,加上@component注解或者spi配置选择一种即可

java 复制代码
int priority(){return 0;}//调整优先级
相关推荐
SimonKing几秒前
Qoder 提供免费 Qwen3.7-Max,无需订阅
java·后端·程序员
dadaobusi9 分钟前
RISC-V 虚拟化:虚拟机TLB处理
java·开发语言
程序猿乐锅19 分钟前
【 苍穹外卖day03 | 菜品管理 】
java·开发语言·数据库·mysql
雾削木21 分钟前
B语言经典教程现代化重构
java·前端·stm32·单片机·嵌入式硬件
凤山老林22 分钟前
JDK 11 升级至 JDK 17
java·开发语言·jdk17·jdk升级·jdk11
指令集梦境27 分钟前
图解:单调栈算法模板(Java语言)
java·开发语言·算法
IronMurphy34 分钟前
多线程问!
java·jvm·spring
vx-Biye_Design35 分钟前
springboot安阳地区研学旅游服务小程序-计算机毕业设计源码12785
java·vue.js·windows·spring boot·tomcat·maven·mybatis
whaledown42 分钟前
Kafka 与 Java 消息队列入门:用订单场景理解核心机制
java·kafka·消息队列·springboot
Moshow郑锴1 小时前
Ubuntu用SDKMAN轻松管理多个Java 版本
java·ubuntu·sdkman