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;}//调整优先级
相关推荐
rannn_11111 小时前
【Redis|高级篇1】分布式缓存|持久化(RDB、AOF)、主从集群、哨兵、分片集群
java·redis·分布式·后端·缓存
PD我是你的真爱粉11 小时前
Redis 持久化、过期删除、淘汰策略与内存碎片全解析
java·redis·bootstrap
Percep_gan11 小时前
在芋道自定义数据权限
java·数据库
哆啦阿梦11 小时前
Java AI 应用工程师 - 完整技能清单
java·开发语言·人工智能
VT LI11 小时前
Lua 源码执行流程全解析:词法分析、语法分析、字节码生成、虚拟机执行与垃圾回收
java·开发语言·lua
凤山老林13 小时前
04-Java JDK, JRE和JVM
java·开发语言·jvm
camellias_20 小时前
【无标题】
java·tomcat
咸鱼2.020 小时前
【java入门到放弃】需要背诵
java·开发语言
椰猫子20 小时前
Java:异常(exception)
java·开发语言
win x21 小时前
Redis 使用~如何在Java中连接使用redis
java·数据库·redis