You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2020/10/12 12:09:47 UTC

[shardingsphere-elasticjob] branch master updated: Redesign SPI factory to make them into one class (#1537) (#1548)

This is an automated email from the ASF dual-hosted git repository.

zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere-elasticjob.git


The following commit(s) were added to refs/heads/master by this push:
     new 5b8199c  Redesign SPI factory to make them into one class (#1537) (#1548)
5b8199c is described below

commit 5b8199cce95330ef4a425837e6a032deec6eefaf
Author: wwj <22...@qq.com>
AuthorDate: Mon Oct 12 20:09:39 2020 +0800

    Redesign SPI factory to make them into one class (#1537) (#1548)
    
    * Redesign SPI factory to make them into one class (#1537)
    
    * fix review problem
---
 .../error/handler/JobErrorHandlerFactory.java      |  4 +-
 .../sharding/JobShardingStrategyFactory.java       | 19 ++-----
 .../JobExecutorServiceHandlerFactory.java          | 19 ++-----
 .../infra/listener/ElasticJobListenerFactory.java  |  4 +-
 .../infra/spi/ElasticJobServiceLoader.java         | 59 ++++++++++++++++++++++
 5 files changed, 71 insertions(+), 34 deletions(-)

diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/JobErrorHandlerFactory.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/JobErrorHandlerFactory.java
index 6bc84cb..5e90e27 100644
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/JobErrorHandlerFactory.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/JobErrorHandlerFactory.java
@@ -33,7 +33,7 @@ public final class JobErrorHandlerFactory {
     private static final String DEFAULT_HANDLER = "LOG";
     
     static {
-        ElasticJobServiceLoader.register(JobErrorHandler.class);
+        ElasticJobServiceLoader.registerTypedService(JobErrorHandler.class);
     }
     
     /**
@@ -50,6 +50,6 @@ public final class JobErrorHandlerFactory {
     }
     
     private static Optional<JobErrorHandler> newHandlerInstance(final String type) {
-        return ElasticJobServiceLoader.newServiceInstances(JobErrorHandler.class).stream().filter(handler -> handler.getType().equalsIgnoreCase(type)).findFirst();
+        return Optional.ofNullable(ElasticJobServiceLoader.newTypedServiceInstance(JobErrorHandler.class, type));
     }
 }
diff --git a/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/handler/sharding/JobShardingStrategyFactory.java b/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/handler/sharding/JobShardingStrategyFactory.java
index acdd44b..a7fe2e2 100644
--- a/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/handler/sharding/JobShardingStrategyFactory.java
+++ b/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/handler/sharding/JobShardingStrategyFactory.java
@@ -20,11 +20,7 @@ package org.apache.shardingsphere.elasticjob.infra.handler.sharding;
 import com.google.common.base.Strings;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.elasticjob.infra.exception.JobConfigurationException;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.ServiceLoader;
+import org.apache.shardingsphere.elasticjob.infra.spi.ElasticJobServiceLoader;
 
 /**
  * Job sharding sharding factory.
@@ -32,14 +28,10 @@ import java.util.ServiceLoader;
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public final class JobShardingStrategyFactory {
     
-    private static final Map<String, JobShardingStrategy> STRATEGIES = new LinkedHashMap<>();
-    
     private static final String DEFAULT_STRATEGY = "AVG_ALLOCATION";
     
     static {
-        for (JobShardingStrategy each : ServiceLoader.load(JobShardingStrategy.class)) {
-            STRATEGIES.put(each.getType(), each);
-        }
+        ElasticJobServiceLoader.registerTypedService(JobShardingStrategy.class);
     }
     
     /**
@@ -50,11 +42,8 @@ public final class JobShardingStrategyFactory {
      */
     public static JobShardingStrategy getStrategy(final String type) {
         if (Strings.isNullOrEmpty(type)) {
-            return STRATEGIES.get(DEFAULT_STRATEGY);
-        }
-        if (!STRATEGIES.containsKey(type)) {
-            throw new JobConfigurationException("Can not find sharding sharding type '%s'.", type);
+            return ElasticJobServiceLoader.getCachedInstance(JobShardingStrategy.class, DEFAULT_STRATEGY);
         }
-        return STRATEGIES.get(type);
+        return ElasticJobServiceLoader.getCachedInstance(JobShardingStrategy.class, type);
     }
 }
diff --git a/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/handler/threadpool/JobExecutorServiceHandlerFactory.java b/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/handler/threadpool/JobExecutorServiceHandlerFactory.java
index 720489d..ff07ced 100644
--- a/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/handler/threadpool/JobExecutorServiceHandlerFactory.java
+++ b/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/handler/threadpool/JobExecutorServiceHandlerFactory.java
@@ -20,11 +20,7 @@ package org.apache.shardingsphere.elasticjob.infra.handler.threadpool;
 import com.google.common.base.Strings;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.elasticjob.infra.exception.JobConfigurationException;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.ServiceLoader;
+import org.apache.shardingsphere.elasticjob.infra.spi.ElasticJobServiceLoader;
 
 /**
  * Job executor service handler factory.
@@ -32,14 +28,10 @@ import java.util.ServiceLoader;
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public final class JobExecutorServiceHandlerFactory {
     
-    private static final Map<String, JobExecutorServiceHandler> HANDLERS = new LinkedHashMap<>();
-    
     private static final String DEFAULT_HANDLER = "CPU";
     
     static {
-        for (JobExecutorServiceHandler each : ServiceLoader.load(JobExecutorServiceHandler.class)) {
-            HANDLERS.put(each.getType(), each);
-        }
+        ElasticJobServiceLoader.registerTypedService(JobExecutorServiceHandler.class);
     }
     
     /**
@@ -50,11 +42,8 @@ public final class JobExecutorServiceHandlerFactory {
      */
     public static JobExecutorServiceHandler getHandler(final String type) {
         if (Strings.isNullOrEmpty(type)) {
-            return HANDLERS.get(DEFAULT_HANDLER);
-        }
-        if (!HANDLERS.containsKey(type)) {
-            throw new JobConfigurationException("Can not find executor service handler type '%s'.", type);
+            return ElasticJobServiceLoader.getCachedInstance(JobExecutorServiceHandler.class, DEFAULT_HANDLER);
         }
-        return HANDLERS.get(type);
+        return ElasticJobServiceLoader.getCachedInstance(JobExecutorServiceHandler.class, type);
     }
 }
diff --git a/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/listener/ElasticJobListenerFactory.java b/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/listener/ElasticJobListenerFactory.java
index 93f9a04..026c6b1 100644
--- a/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/listener/ElasticJobListenerFactory.java
+++ b/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/listener/ElasticJobListenerFactory.java
@@ -30,7 +30,7 @@ import java.util.Optional;
 public final class ElasticJobListenerFactory {
     
     static {
-        ElasticJobServiceLoader.register(ElasticJobListener.class);
+        ElasticJobServiceLoader.registerTypedService(ElasticJobListener.class);
     }
     
     /**
@@ -40,6 +40,6 @@ public final class ElasticJobListenerFactory {
      * @return optional job listener instance
      */
     public static Optional<ElasticJobListener> createListener(final String type) {
-        return ElasticJobServiceLoader.newServiceInstances(ElasticJobListener.class).stream().filter(listener -> listener.getType().equalsIgnoreCase(type)).findFirst();
+        return Optional.ofNullable(ElasticJobServiceLoader.newTypedServiceInstance(ElasticJobListener.class, type));
     }
 }
diff --git a/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/spi/ElasticJobServiceLoader.java b/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/spi/ElasticJobServiceLoader.java
index 78024f7..06b3575 100644
--- a/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/spi/ElasticJobServiceLoader.java
+++ b/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/spi/ElasticJobServiceLoader.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.elasticjob.infra.spi;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
+import org.apache.shardingsphere.elasticjob.infra.exception.JobConfigurationException;
 import org.apache.shardingsphere.elasticjob.infra.spi.exception.ServiceLoaderInstantiationException;
 
 import java.lang.reflect.InvocationTargetException;
@@ -38,6 +39,10 @@ public final class ElasticJobServiceLoader {
     
     private static final ConcurrentMap<Class<?>, Collection<Class<?>>> SERVICES = new ConcurrentHashMap<>();
     
+    private static final ConcurrentMap<Class<?>, ConcurrentMap<String, TypedSPI>> TYPED_SERVICES = new ConcurrentHashMap<>();
+
+    private static final ConcurrentMap<Class<?>, ConcurrentMap<String, Class<?>>> TYPED_SERVICE_CLASSES = new ConcurrentHashMap<>();
+
     /**
      * Register SPI service.
      *
@@ -76,4 +81,58 @@ public final class ElasticJobServiceLoader {
             throw new ServiceLoaderInstantiationException(clazz, ex.getCause());
         }
     }
+
+    /**
+     * Register typeSPI service.
+     *
+     * @param typedService specific service type
+     * @param <T> type of service
+     */
+    public static <T> void registerTypedService(final Class<T> typedService) {
+        if (!TypedSPI.class.isAssignableFrom(typedService)) {
+            throw new IllegalArgumentException("Cannot register @" + typedService.getName() + "as a typed service, because its not a subClass of @" + typedService);
+        }
+        if (TYPED_SERVICES.containsKey(typedService)) {
+            return;
+        }
+        ServiceLoader.load(typedService).forEach(each -> registerTypedServiceClass(typedService, (TypedSPI) each));
+    }
+
+    private static <T> void registerTypedServiceClass(final Class<T> typedService, final TypedSPI instance) {
+        TYPED_SERVICES.computeIfAbsent(typedService, unused -> new ConcurrentHashMap<>()).putIfAbsent(instance.getType(), instance);
+        TYPED_SERVICE_CLASSES.computeIfAbsent(typedService, unused -> new ConcurrentHashMap<>()).putIfAbsent(instance.getType(), instance.getClass());
+    }
+
+    /**
+     * Get cached instance.
+     *
+     * @param typedService service type
+     * @param type         specific service type
+     * @param <T>          specific type of service
+     * @return cached service instance
+     */
+    public static <T extends TypedSPI> T getCachedInstance(final Class<T> typedService, final String type) {
+        T instance = TYPED_SERVICES.containsKey(typedService) ? (T) TYPED_SERVICES.get(typedService).get(type) : null;
+        if (null == instance) {
+            throw new JobConfigurationException("Cannot find a cached typed service instance by the interface: @" + typedService.getName() + "and type: " + type);
+        }
+        return instance;
+    }
+
+    /**
+     * New typed instance.
+     *
+     * @param typedService service type
+     * @param type         specific service type
+     * @param <T>          specific type of service
+     * @return specific typed service instance
+     */
+    public static <T extends TypedSPI> T newTypedServiceInstance(final Class<T> typedService, final String type) {
+        Class<?> instanceClass = TYPED_SERVICE_CLASSES.containsKey(typedService) ? TYPED_SERVICE_CLASSES.get(typedService).get(type) : null;
+        if (null == instanceClass) {
+            throw new JobConfigurationException("Cannot find a typed service class by the interface: @" + typedService.getName() + "and type: " + type);
+        }
+        return (T) newServiceInstance(instanceClass);
+    }
+
 }