From c04241d3b33042dc85629a24db5fa164f404d6b3 Mon Sep 17 00:00:00 2001 From: click33 <2393584716@qq.com> Date: Mon, 24 Feb 2025 19:48:33 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20SPI=20=E6=8F=92=E4=BB=B6=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E6=94=B9=E4=B8=BA=20satoken?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/SaTokenPluginException.java | 10 ++++ .../satoken/plugin/SaTokenPluginHolder.java | 56 ++++++++++++++++++- sa-token-demo/sa-token-demo-test/pom.xml | 8 +-- .../java/com/pj/satoken/SaTokenConfigure.java | 2 +- .../cn.dev33.satoken.plugin.SaTokenPlugin | 0 .../cn.dev33.satoken.plugin.SaTokenPlugin | 0 .../cn.dev33.satoken.plugin.SaTokenPlugin | 0 .../cn.dev33.satoken.plugin.SaTokenPlugin | 0 .../cn.dev33.satoken.plugin.SaTokenPlugin | 0 .../cn.dev33.satoken.plugin.SaTokenPlugin | 0 .../cn.dev33.satoken.plugin.SaTokenPlugin | 0 11 files changed, 68 insertions(+), 8 deletions(-) rename sa-token-plugin/sa-token-dubbo/src/main/resources/META-INF/{services => satoken}/cn.dev33.satoken.plugin.SaTokenPlugin (100%) rename sa-token-plugin/sa-token-dubbo3/src/main/resources/META-INF/{services => satoken}/cn.dev33.satoken.plugin.SaTokenPlugin (100%) rename sa-token-plugin/sa-token-fastjson/src/main/resources/META-INF/{services => satoken}/cn.dev33.satoken.plugin.SaTokenPlugin (100%) rename sa-token-plugin/sa-token-fastjson2/src/main/resources/META-INF/{services => satoken}/cn.dev33.satoken.plugin.SaTokenPlugin (100%) rename sa-token-plugin/sa-token-hutool-timed-cache/src/main/resources/META-INF/{services => satoken}/cn.dev33.satoken.plugin.SaTokenPlugin (100%) rename sa-token-plugin/sa-token-jackson/src/main/resources/META-INF/{services => satoken}/cn.dev33.satoken.plugin.SaTokenPlugin (100%) rename sa-token-plugin/sa-token-temp-jwt/src/main/resources/META-INF/{services => satoken}/cn.dev33.satoken.plugin.SaTokenPlugin (100%) diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/exception/SaTokenPluginException.java b/sa-token-core/src/main/java/cn/dev33/satoken/exception/SaTokenPluginException.java index 13b76a86..3b2b706f 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/exception/SaTokenPluginException.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/exception/SaTokenPluginException.java @@ -45,4 +45,14 @@ public class SaTokenPluginException extends SaTokenException { super(cause); } + /** + * 一个异常:代表插件安装过程中出现异常 + * + * @param message 异常描述 + * @param cause 异常对象 + */ + public SaTokenPluginException(String message, Throwable cause) { + super(message, cause); + } + } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/plugin/SaTokenPluginHolder.java b/sa-token-core/src/main/java/cn/dev33/satoken/plugin/SaTokenPluginHolder.java index d8935069..9bac40a3 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/plugin/SaTokenPluginHolder.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/plugin/SaTokenPluginHolder.java @@ -19,10 +19,14 @@ import cn.dev33.satoken.SaManager; import cn.dev33.satoken.exception.SaTokenPluginException; import cn.dev33.satoken.fun.hooks.SaTokenPluginHookFunction; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; import java.lang.reflect.InvocationTargetException; +import java.net.URL; import java.util.ArrayList; +import java.util.Enumeration; import java.util.List; -import java.util.ServiceLoader; /** * Sa-Token 插件管理器,管理所有插件的加载与卸载 @@ -38,13 +42,18 @@ public class SaTokenPluginHolder { public static SaTokenPluginHolder instance = new SaTokenPluginHolder(); - // ------------------- 插件初始化相关 ------------------- + // ------------------- 插件管理器初始化相关 ------------------- /** * 是否已经加载过插件 */ public boolean isLoader = false; + /** + * SPI 文件所在目录名称 + */ + public String spiDir = "satoken"; + /** * 初始化加载所有插件(多次调用只会执行一次) */ @@ -58,16 +67,57 @@ public class SaTokenPluginHolder { /** * 根据 SPI 机制加载所有插件 + *

+ * 加载所有 jar 下 /META-INF/satoken/ 目录下 cn.dev33.satoken.plugin.SaTokenPlugin 文件指定的实现类 + *

*/ public synchronized void loaderPlugins() { SaManager.getLog().info("SPI 插件加载开始 ..."); - ServiceLoader plugins = ServiceLoader.load(SaTokenPlugin.class); + List plugins = _loaderPluginsBySpi(SaTokenPlugin.class, spiDir); for (SaTokenPlugin plugin : plugins) { installPlugin(plugin); } SaManager.getLog().info("SPI 插件加载结束 ..."); } + /** + * 自定义 SPI 读取策略 (无状态函数) + * @param serviceInterface SPI 接口 + * @param dirName 目录名称 + * @return / + * @param / + */ + protected List _loaderPluginsBySpi(Class serviceInterface, String dirName) { + String path = "META-INF/" + dirName + "/" + serviceInterface.getName(); + List providers = new ArrayList<>(); + try { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + Enumeration resources = classLoader.getResources(path); + while (resources.hasMoreElements()) { + URL url = resources.nextElement(); + try (InputStream is = url.openStream()) { + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + String line; + while ((line = reader.readLine()) != null) { + line = line.trim(); + // 忽略空行和注释行 + if (!line.isEmpty() && !line.startsWith("#")) { + Class clazz = Class.forName(line, true, classLoader); + T instance = serviceInterface.cast(clazz.getDeclaredConstructor().newInstance()); + providers.add(instance); + } + } + } catch (Exception e) { + throw new SaTokenPluginException("SPI 插件加载失败: " + e.getMessage(), e); + } + } + } catch (Exception e) { + throw new RuntimeException("SPI 插件加载失败: " + e.getMessage(), e); + } + return providers; + } + + // ------------------- 插件管理 ------------------- diff --git a/sa-token-demo/sa-token-demo-test/pom.xml b/sa-token-demo/sa-token-demo-test/pom.xml index 3520135f..64ff9c72 100644 --- a/sa-token-demo/sa-token-demo-test/pom.xml +++ b/sa-token-demo/sa-token-demo-test/pom.xml @@ -36,10 +36,10 @@ - cn.dev33 - sa-token-spring-boot-starter - ${sa-token.version} - + cn.dev33 + sa-token-spring-boot-starter + ${sa-token.version} + cn.hutool diff --git a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/SaTokenConfigure.java b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/SaTokenConfigure.java index 745f7aa3..42a71bbc 100644 --- a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/SaTokenConfigure.java +++ b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/SaTokenConfigure.java @@ -105,7 +105,7 @@ public class SaTokenConfigure implements WebMvcConfigurer { .onAfterInstall(SaTokenPluginForJackson.class, plugin -> { System.out.println("SaTokenPluginForJackson 插件安装后置钩子2..."); }) - + ; } diff --git a/sa-token-plugin/sa-token-dubbo/src/main/resources/META-INF/services/cn.dev33.satoken.plugin.SaTokenPlugin b/sa-token-plugin/sa-token-dubbo/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin similarity index 100% rename from sa-token-plugin/sa-token-dubbo/src/main/resources/META-INF/services/cn.dev33.satoken.plugin.SaTokenPlugin rename to sa-token-plugin/sa-token-dubbo/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin diff --git a/sa-token-plugin/sa-token-dubbo3/src/main/resources/META-INF/services/cn.dev33.satoken.plugin.SaTokenPlugin b/sa-token-plugin/sa-token-dubbo3/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin similarity index 100% rename from sa-token-plugin/sa-token-dubbo3/src/main/resources/META-INF/services/cn.dev33.satoken.plugin.SaTokenPlugin rename to sa-token-plugin/sa-token-dubbo3/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin diff --git a/sa-token-plugin/sa-token-fastjson/src/main/resources/META-INF/services/cn.dev33.satoken.plugin.SaTokenPlugin b/sa-token-plugin/sa-token-fastjson/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin similarity index 100% rename from sa-token-plugin/sa-token-fastjson/src/main/resources/META-INF/services/cn.dev33.satoken.plugin.SaTokenPlugin rename to sa-token-plugin/sa-token-fastjson/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin diff --git a/sa-token-plugin/sa-token-fastjson2/src/main/resources/META-INF/services/cn.dev33.satoken.plugin.SaTokenPlugin b/sa-token-plugin/sa-token-fastjson2/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin similarity index 100% rename from sa-token-plugin/sa-token-fastjson2/src/main/resources/META-INF/services/cn.dev33.satoken.plugin.SaTokenPlugin rename to sa-token-plugin/sa-token-fastjson2/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin diff --git a/sa-token-plugin/sa-token-hutool-timed-cache/src/main/resources/META-INF/services/cn.dev33.satoken.plugin.SaTokenPlugin b/sa-token-plugin/sa-token-hutool-timed-cache/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin similarity index 100% rename from sa-token-plugin/sa-token-hutool-timed-cache/src/main/resources/META-INF/services/cn.dev33.satoken.plugin.SaTokenPlugin rename to sa-token-plugin/sa-token-hutool-timed-cache/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin diff --git a/sa-token-plugin/sa-token-jackson/src/main/resources/META-INF/services/cn.dev33.satoken.plugin.SaTokenPlugin b/sa-token-plugin/sa-token-jackson/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin similarity index 100% rename from sa-token-plugin/sa-token-jackson/src/main/resources/META-INF/services/cn.dev33.satoken.plugin.SaTokenPlugin rename to sa-token-plugin/sa-token-jackson/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin diff --git a/sa-token-plugin/sa-token-temp-jwt/src/main/resources/META-INF/services/cn.dev33.satoken.plugin.SaTokenPlugin b/sa-token-plugin/sa-token-temp-jwt/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin similarity index 100% rename from sa-token-plugin/sa-token-temp-jwt/src/main/resources/META-INF/services/cn.dev33.satoken.plugin.SaTokenPlugin rename to sa-token-plugin/sa-token-temp-jwt/src/main/resources/META-INF/satoken/cn.dev33.satoken.plugin.SaTokenPlugin