diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/spi/ListServiceLoader.java b/hutool-core/src/main/java/org/dromara/hutool/core/spi/ListServiceLoader.java index 8f59cce99..f80a4f63c 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/spi/ListServiceLoader.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/spi/ListServiceLoader.java @@ -41,6 +41,16 @@ import java.util.List; *
+ * 服务文件默认位于"META-INF/services/"下,文件名为服务接口类全名。内容类似于: + *
+ * # 我是注释 + * hutool.service.Service1 + * hutool.service.Service2 + *+ *
+ * 通过调用{@link #getService(int)}方法,传入序号,即可获取对应服务。
+ *
* @param
+ * 内容类似于:
+ *
+ * 通过调用{@link #getService(String)}方法,传入等号前的名称,即可获取对应服务。
*
* @param 服务类型
* @author looly
* @since 6.0.0
@@ -145,7 +155,7 @@ public class ListServiceLoader extends AbsServiceLoader {
*/
public S getService(final int index) {
final String serviceClassName = this.serviceNames.get(index);
- if(null == serviceClassName){
+ if (null == serviceClassName) {
return null;
}
return getServiceByName(serviceClassName);
@@ -155,6 +165,7 @@ public class ListServiceLoader extends AbsServiceLoader {
public Iterator iterator() {
return new Iterator() {
private final Iterator extends AbsServiceLoader {
*/
private S createService(final String serviceClassName) {
return AccessUtil.doPrivileged(() ->
- ConstructorUtil.newInstance(ClassLoaderUtil.loadClass(serviceClassName)),
+ ConstructorUtil.newInstance(ClassLoaderUtil.loadClass(serviceClassName)),
this.acc);
}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/spi/KVServiceLoader.java b/hutool-core/src/main/java/org/dromara/hutool/core/spi/MapServiceLoader.java
similarity index 81%
rename from hutool-core/src/main/java/org/dromara/hutool/core/spi/KVServiceLoader.java
rename to hutool-core/src/main/java/org/dromara/hutool/core/spi/MapServiceLoader.java
index e84c2ea0a..ec595dcf5 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/spi/KVServiceLoader.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/spi/MapServiceLoader.java
@@ -20,16 +20,29 @@ import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.util.AccessUtil;
import java.nio.charset.Charset;
-import java.util.*;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Properties;
/**
- * 键值对服务加载器,使用{@link Properties}加载并存储服务
+ * 键值对服务加载器,使用{@link Properties}加载并存储服务
+ * 服务文件默认位于"META-INF/hutool/"下,文件名为服务接口类全名。
+ *
+ *
+ * # 我是注释
+ * service1 = hutool.service.Service1
+ * service2 = hutool.service.Service2
+ *
+ * 服务类型
* @author looly
* @since 6.0.0
*/
-public class KVServiceLoader extends AbsServiceLoader {
+public class MapServiceLoader extends AbsServiceLoader {
private static final String PREFIX_HUTOOL = "META-INF/hutool/";
@@ -42,7 +55,7 @@ public class KVServiceLoader extends AbsServiceLoader {
* @param serviceClass 服务名称
* @return KVServiceLoader
*/
- public static KVServiceLoader of(final Class serviceClass) {
+ public static MapServiceLoader of(final Class serviceClass) {
return of(serviceClass, null);
}
@@ -54,7 +67,7 @@ public class KVServiceLoader extends AbsServiceLoader {
* @param classLoader 自定义类加载器, {@code null}表示使用默认当前的类加载器
* @return KVServiceLoader
*/
- public static KVServiceLoader of(final Class serviceClass, final ClassLoader classLoader) {
+ public static MapServiceLoader of(final Class serviceClass, final ClassLoader classLoader) {
return of(PREFIX_HUTOOL, serviceClass, classLoader);
}
@@ -67,9 +80,9 @@ public class KVServiceLoader extends AbsServiceLoader {
* @param classLoader 自定义类加载器, {@code null}表示使用默认当前的类加载器
* @return KVServiceLoader
*/
- public static KVServiceLoader of(final String pathPrefix, final Class serviceClass,
- final ClassLoader classLoader) {
- return new KVServiceLoader<>(pathPrefix, serviceClass, classLoader, null);
+ public static MapServiceLoader of(final String pathPrefix, final Class serviceClass,
+ final ClassLoader classLoader) {
+ return new MapServiceLoader<>(pathPrefix, serviceClass, classLoader, null);
}
// endregion
@@ -85,8 +98,8 @@ public class KVServiceLoader extends AbsServiceLoader {
* @param classLoader 自定义类加载器, {@code null}表示使用默认当前的类加载器
* @param charset 编码,默认UTF-8
*/
- public KVServiceLoader(final String pathPrefix, final Class serviceClass,
- final ClassLoader classLoader, final Charset charset) {
+ public MapServiceLoader(final String pathPrefix, final Class serviceClass,
+ final ClassLoader classLoader, final Charset charset) {
super(pathPrefix, serviceClass, classLoader, charset);
this.serviceCache = new SimpleCache<>(new HashMap<>());
@@ -141,6 +154,7 @@ public class KVServiceLoader extends AbsServiceLoader {
return new Iterator() {
private final Iterator extends AbsServiceLoader {
}
// region ----- private methods
+
/**
* 创建服务,无缓存
*
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/spi/SpiUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/spi/SpiUtil.java
index 40998df9c..cdcc05408 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/spi/SpiUtil.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/spi/SpiUtil.java
@@ -25,12 +25,23 @@ public class SpiUtil {
/**
* 加载第一个可用服务,如果用户定义了多个接口实现类,只获取第一个不报错的服务
*
- * @param 服务类型
* @param clazz 服务接口
* @return 第一个服务接口实现对象,无实现返回{@code null}
*/
- public static S loadFirstAvailable(final Class clazz) {
+ return loadFirstAvailable(loadList(clazz));
+ }
+
+ /**
+ * 加载第一个可用服务,如果用户定义了多个接口实现类,只获取第一个不报错的服务
+ *
+ * @param 服务类型
+ * @param serviceLoader {@link ServiceLoader}
+ * @return 第一个服务接口实现对象,无实现返回{@code null}
+ */
+ public static S loadFirstAvailable(final ServiceLoader serviceLoader) {
+ final Iterator iterator = serviceLoader.iterator();
while (iterator.hasNext()) {
try {
return iterator.next();
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/spi/package-info.java b/hutool-core/src/main/java/org/dromara/hutool/core/spi/package-info.java
index bc41e33de..edb2c65f8 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/spi/package-info.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/spi/package-info.java
@@ -11,6 +11,10 @@
*/
/**
- * 服务提供接口SPI(Service Provider interface)机制相关封装
+ * 服务提供接口SPI(Service Provider interface)机制相关封装,包括:
+ *
+ *
*/
package org.dromara.hutool.core.spi;
diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/spi/SpiUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/spi/SpiUtilTest.java
new file mode 100644
index 000000000..7596bbeb2
--- /dev/null
+++ b/hutool-core/src/test/java/org/dromara/hutool/core/spi/SpiUtilTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2023 looly(loolly@aliyun.com)
+ * Hutool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+package org.dromara.hutool.core.spi;
+
+import org.dromara.hutool.core.exceptions.UtilException;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class SpiUtilTest {
+
+ @Test
+ void loadFirstAvailableTest() {
+ final MapServiceLoader