From 1e1f821e46a45002c8db02bb65fe91a7d4d5221f Mon Sep 17 00:00:00 2001 From: "chen.ma" Date: Sun, 11 Jul 2021 00:57:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8F=90=E4=BE=9B=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E6=B1=A0=20SPI=20=E5=85=AC=E5=85=B1=E7=BB=84?= =?UTF-8?q?=E4=BB=B6.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../starter/spi/DynamicTpServiceLoader.java | 48 +++++++++++++++++++ .../ServiceLoaderInstantiationException.java | 16 +++++++ 2 files changed, 64 insertions(+) create mode 100644 dynamic-threadpool-spring-boot-starter/src/main/java/io/dynamic/threadpool/starter/spi/DynamicTpServiceLoader.java create mode 100644 dynamic-threadpool-spring-boot-starter/src/main/java/io/dynamic/threadpool/starter/spi/exception/ServiceLoaderInstantiationException.java diff --git a/dynamic-threadpool-spring-boot-starter/src/main/java/io/dynamic/threadpool/starter/spi/DynamicTpServiceLoader.java b/dynamic-threadpool-spring-boot-starter/src/main/java/io/dynamic/threadpool/starter/spi/DynamicTpServiceLoader.java new file mode 100644 index 00000000..9bfbe9f2 --- /dev/null +++ b/dynamic-threadpool-spring-boot-starter/src/main/java/io/dynamic/threadpool/starter/spi/DynamicTpServiceLoader.java @@ -0,0 +1,48 @@ +package io.dynamic.threadpool.starter.spi; + +import io.dynamic.threadpool.starter.spi.exception.ServiceLoaderInstantiationException; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +/** + * Dynamic ThreadPool Service Loader. + * + * @author chen.ma + * @date 2021/7/10 23:45 + */ +public class DynamicTpServiceLoader { + + private static final Map, Collection> SERVICES = new ConcurrentHashMap(); + + public static void register(final Class serviceInterface) { + if (!SERVICES.containsKey(serviceInterface)) { + SERVICES.put(serviceInterface, load(serviceInterface)); + } + } + + private static Collection load(final Class serviceInterface) { + Collection result = new LinkedList<>(); + for (T each : ServiceLoader.load(serviceInterface)) { + result.add(each); + } + return result; + } + + public static Collection getSingletonServiceInstances(final Class service) { + return (Collection) SERVICES.getOrDefault(service, Collections.emptyList()); + } + + public static Collection newServiceInstances(final Class service) { + return SERVICES.containsKey(service) ? SERVICES.get(service).stream().map(each -> (T) newServiceInstance(each.getClass())).collect(Collectors.toList()) : Collections.emptyList(); + } + + private static Object newServiceInstance(final Class clazz) { + try { + return clazz.newInstance(); + } catch (final InstantiationException | IllegalAccessException ex) { + throw new ServiceLoaderInstantiationException(clazz, ex); + } + } +} diff --git a/dynamic-threadpool-spring-boot-starter/src/main/java/io/dynamic/threadpool/starter/spi/exception/ServiceLoaderInstantiationException.java b/dynamic-threadpool-spring-boot-starter/src/main/java/io/dynamic/threadpool/starter/spi/exception/ServiceLoaderInstantiationException.java new file mode 100644 index 00000000..718d68bf --- /dev/null +++ b/dynamic-threadpool-spring-boot-starter/src/main/java/io/dynamic/threadpool/starter/spi/exception/ServiceLoaderInstantiationException.java @@ -0,0 +1,16 @@ +package io.dynamic.threadpool.starter.spi.exception; + +/** + * Service loader instantiation exception. + * + * @author chen.ma + * @date 2021/7/10 23:48 + */ +public class ServiceLoaderInstantiationException extends RuntimeException { + + public ServiceLoaderInstantiationException(final Class clazz, final Exception cause) { + super(String.format("Can not find public default constructor for SPI class `%s`", clazz.getName()), cause); + } + +} +