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);
+ }
+
}