From 64500b113a05d992a1a2d59db8536e40ba1b1110 Mon Sep 17 00:00:00 2001 From: Redkale <8730487+redkale@users.noreply.github.com> Date: Sat, 6 Jun 2020 18:50:18 +0800 Subject: [PATCH] --- src/org/redkale/boot/Application.java | 48 +++++++++++++++---- src/org/redkale/boot/NodeServer.java | 33 ++++++++++++- src/org/redkale/cluster/ClusterAgent.java | 3 ++ src/org/redkale/mq/MessageAgent.java | 3 ++ src/org/redkale/source/CacheMemorySource.java | 5 ++ src/org/redkale/source/CacheSource.java | 5 +- 6 files changed, 84 insertions(+), 13 deletions(-) diff --git a/src/org/redkale/boot/Application.java b/src/org/redkale/boot/Application.java index 7d3b4e47d..60f393ef7 100644 --- a/src/org/redkale/boot/Application.java +++ b/src/org/redkale/boot/Application.java @@ -323,12 +323,26 @@ public final class Application { AnyValue clusterConf = resources.getAnyValue("cluster"); if (clusterConf != null) { try { - Class type = classLoader.loadClass(clusterConf.getValue("value")); - if (!ClusterAgent.class.isAssignableFrom(type)) { - logger.log(Level.SEVERE, "load application cluster resource, but not " + ClusterAgent.class.getSimpleName() + " error: " + clusterConf); + String classval = clusterConf.getValue("value"); + if (classval == null || classval.isEmpty()) { + Iterator it = ServiceLoader.load(ClusterAgent.class, classLoader).iterator(); + while (it.hasNext()) { + ClusterAgent agent = it.next(); + if (agent.match(clusterConf)) { + cluster = agent; + cluster.setConfig(clusterConf); + break; + } + } + if (cluster == null) logger.log(Level.SEVERE, "load application cluster resource, but not found name='value' value error: " + clusterConf); } else { - cluster = (ClusterAgent) type.getDeclaredConstructor().newInstance(); - cluster.setConfig(clusterConf); + Class type = classLoader.loadClass(clusterConf.getValue("value")); + if (!ClusterAgent.class.isAssignableFrom(type)) { + logger.log(Level.SEVERE, "load application cluster resource, but not found " + ClusterAgent.class.getSimpleName() + " implements class error: " + clusterConf); + } else { + cluster = (ClusterAgent) type.getDeclaredConstructor().newInstance(); + cluster.setConfig(clusterConf); + } } } catch (Exception e) { logger.log(Level.SEVERE, "load application cluster resource error: " + clusterConf, e); @@ -344,12 +358,26 @@ public final class Application { String mqname = mqConf.getValue("name", ""); if (mqnames.contains(mqname)) throw new RuntimeException("mq.name(" + mqname + ") is repeat"); try { - Class type = classLoader.loadClass(mqConf.getValue("value")); - if (!MessageAgent.class.isAssignableFrom(type)) { - logger.log(Level.SEVERE, "load application mq resource, but not " + MessageAgent.class.getSimpleName() + " error: " + mqConf); + String classval = mqConf.getValue("value"); + if (classval == null || classval.isEmpty()) { + Iterator it = ServiceLoader.load(MessageAgent.class, classLoader).iterator(); + while (it.hasNext()) { + MessageAgent agent = it.next(); + if (agent.match(mqConf)) { + mqs[i] = agent; + mqs[i].setConfig(mqConf); + break; + } + } + if (mqs[i] == null) logger.log(Level.SEVERE, "load application mq resource, but not found name='value' value error: " + mqConf); } else { - mqs[i] = (MessageAgent) type.getDeclaredConstructor().newInstance(); - mqs[i].setConfig(mqConf); + Class type = classLoader.loadClass(classval); + if (!MessageAgent.class.isAssignableFrom(type)) { + logger.log(Level.SEVERE, "load application mq resource, but not found " + MessageAgent.class.getSimpleName() + " implements class error: " + mqConf); + } else { + mqs[i] = (MessageAgent) type.getDeclaredConstructor().newInstance(); + mqs[i].setConfig(mqConf); + } } } catch (Exception e) { logger.log(Level.SEVERE, "load application mq resource error: " + mqs[i], e); diff --git a/src/org/redkale/boot/NodeServer.java b/src/org/redkale/boot/NodeServer.java index 59e3a6c59..fb00ec63d 100644 --- a/src/org/redkale/boot/NodeServer.java +++ b/src/org/redkale/boot/NodeServer.java @@ -211,7 +211,20 @@ public abstract class NodeServer { if (resources != null) { for (AnyValue sourceConf : resources.getAnyValues("source")) { try { - Class type = serverClassLoader.loadClass(sourceConf.getValue("value")); + String classval = sourceConf.getValue("value"); + Class type = null; + if (classval == null || classval.isEmpty()) { + Iterator it = ServiceLoader.load(CacheSource.class, serverClassLoader).iterator(); + while (it.hasNext()) { + CacheSource s = it.next(); + if (s.match(sourceConf)) { + type = s.getClass(); + break; + } + } + } else { + type = serverClassLoader.loadClass(classval); + } if (type == DataSource.class) { type = DataMemorySource.class; for (AnyValue itemConf : sourceConf.getAnyValues("property")) { @@ -321,7 +334,23 @@ public abstract class NodeServer { SimpleEntry resEntry2 = dataResources.get(resourceName); sourceConf = resEntry2 == null ? null : resEntry2.getValue(); } - final Class sourceType = sourceConf == null ? CacheMemorySource.class : serverClassLoader.loadClass(sourceConf.getValue("value")); + Class sourceType0 = CacheMemorySource.class; + if (sourceConf != null) { + String classval = sourceConf.getValue("value"); + if (classval == null || classval.isEmpty()) { + Iterator it = ServiceLoader.load(CacheSource.class, serverClassLoader).iterator(); + while (it.hasNext()) { + CacheSource s = it.next(); + if (s.match(sourceConf)) { + sourceType0 = s.getClass(); + break; + } + } + } else { + sourceType0 = serverClassLoader.loadClass(classval); + } + } + final Class sourceType = sourceType0; Object source = null; if (CacheSource.class.isAssignableFrom(sourceType)) { // CacheSource source = (CacheSource) Sncp.createLocalService(serverClassLoader, resourceName, sourceType, client == null ? null : client.getMessageAgent(), appResFactory, appSncpTranFactory, sncpAddr, null, Sncp.getConf(srcService)); diff --git a/src/org/redkale/cluster/ClusterAgent.java b/src/org/redkale/cluster/ClusterAgent.java index 8080f9970..debea59c7 100644 --- a/src/org/redkale/cluster/ClusterAgent.java +++ b/src/org/redkale/cluster/ClusterAgent.java @@ -74,6 +74,9 @@ public abstract class ClusterAgent { public void destroy(AnyValue config) { } + //ServiceLoader时判断配置是否符合当前实现类 + public abstract boolean match(AnyValue config); + public boolean containsProtocol(String protocol) { if (protocol == null || protocol.isEmpty()) return false; return protocols == null || Utility.contains(protocols, protocol.toUpperCase()); diff --git a/src/org/redkale/mq/MessageAgent.java b/src/org/redkale/mq/MessageAgent.java index ce0832ff0..27bce75db 100644 --- a/src/org/redkale/mq/MessageAgent.java +++ b/src/org/redkale/mq/MessageAgent.java @@ -57,6 +57,9 @@ public abstract class MessageAgent { public void init(AnyValue config) { } + //ServiceLoader时判断配置是否符合当前实现类 + public abstract boolean match(AnyValue config); + public final CompletableFuture createSncpRespFuture(AtomicLong counter, MessageRecord message) { return this.sncpRespProcessor.createFuture(message.getSeqid(), counter); } diff --git a/src/org/redkale/source/CacheMemorySource.java b/src/org/redkale/source/CacheMemorySource.java index 414d2ae79..049cfd6e9 100644 --- a/src/org/redkale/source/CacheMemorySource.java +++ b/src/org/redkale/source/CacheMemorySource.java @@ -90,6 +90,11 @@ public class CacheMemorySource extends AbstractService impleme return "memory"; } + @Override //ServiceLoader时判断配置是否符合当前实现类 + public boolean match(AnyValue config) { + return false; + } + @Override @SuppressWarnings("unchecked") public void init(AnyValue conf) { diff --git a/src/org/redkale/source/CacheSource.java b/src/org/redkale/source/CacheSource.java index ce99421b2..5b25179bb 100644 --- a/src/org/redkale/source/CacheSource.java +++ b/src/org/redkale/source/CacheSource.java @@ -11,7 +11,7 @@ import java.util.concurrent.*; import java.util.function.Function; import org.redkale.convert.*; import org.redkale.convert.json.JsonFactory; -import org.redkale.util.ConstructorParameters; +import org.redkale.util.*; /** * Redkale中缓存数据源的核心类。 主要供业务开发者使用, 技术开发者提供CacheSource的实现。
@@ -34,6 +34,9 @@ public interface CacheSource { public void initTransient(boolean flag); + //ServiceLoader时判断配置是否符合当前实现类 + public boolean match(AnyValue config); + default boolean isOpen() { return true; }