From 49405c509ba2ec09ecce0043ba9befda6a5f0f7e Mon Sep 17 00:00:00 2001 From: redkale Date: Thu, 29 Feb 2024 14:29:08 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96ResourceTypeLoader?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/redkale/boot/Application.java | 306 ++++++++++++------ .../java/org/redkale/boot/NodeHttpServer.java | 119 +++---- .../java/org/redkale/boot/NodeServer.java | 180 +++++++---- .../org/redkale/inject/ResourceFactory.java | 9 +- .../redkale/inject/ResourceTypeLoader.java | 3 + .../redkale/mq/spi/MessageModuleEngine.java | 10 +- .../java/org/redkale/source/FilterNode.java | 4 +- .../source/spi/SourceModuleEngine.java | 22 +- 8 files changed, 419 insertions(+), 234 deletions(-) diff --git a/src/main/java/org/redkale/boot/Application.java b/src/main/java/org/redkale/boot/Application.java index c582a246a..df907de01 100644 --- a/src/main/java/org/redkale/boot/Application.java +++ b/src/main/java/org/redkale/boot/Application.java @@ -383,136 +383,240 @@ public final class Application { @Override public Object load(ResourceFactory rf, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment) { try { - Class type = field.getType(); - if (type == Application.class) { - field.set(srcObj, application); - return application; - } else if (type == ResourceFactory.class) { - boolean serv = RESNAME_SERVER_RESFACTORY.equals(resourceName) || resourceName.equalsIgnoreCase("server"); - ResourceFactory rs = serv ? rf : (resourceName.isEmpty() ? application.resourceFactory : null); - field.set(srcObj, rs); - return rs; - } else if (type == NodeSncpServer.class) { - NodeServer server = null; - for (NodeServer ns : application.getNodeServers()) { - if (ns.getClass() != NodeSncpServer.class) { - continue; - } - if (resourceName.equals(ns.server.getName())) { - server = ns; - break; - } - } - field.set(srcObj, server); - return server; - } else if (type == NodeHttpServer.class) { - NodeServer server = null; - for (NodeServer ns : application.getNodeServers()) { - if (ns.getClass() != NodeHttpServer.class) { - continue; - } - if (resourceName.equals(ns.server.getName())) { - server = ns; - break; - } - } - field.set(srcObj, server); - return server; - } else if (type == NodeWatchServer.class) { - NodeServer server = null; - for (NodeServer ns : application.getNodeServers()) { - if (ns.getClass() != NodeWatchServer.class) { - continue; - } - if (resourceName.equals(ns.server.getName())) { - server = ns; - break; - } - } - field.set(srcObj, server); - return server; - } -// if (type == WatchFactory.class) { -// field.setex(src, application.watchFactory); -// } - return null; + field.set(srcObj, application); + return application; } catch (Exception e) { logger.log(Level.SEVERE, "Resource inject error", e); return null; } } + @Override + public Type resourceType() { + return Application.class; + } + @Override public boolean autoNone() { return false; } + }); + this.resourceFactory.register(new ResourceTypeLoader() { - }, Application.class, ResourceFactory.class, NodeSncpServer.class, NodeHttpServer.class, NodeWatchServer.class); + @Override + public Object load(ResourceFactory rf, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment) { + try { + boolean serv = RESNAME_SERVER_RESFACTORY.equals(resourceName) || resourceName.equalsIgnoreCase("server"); + ResourceFactory rs = serv ? rf : (resourceName.isEmpty() ? application.resourceFactory : null); + field.set(srcObj, rs); + return rs; + } catch (Exception e) { + logger.log(Level.SEVERE, "Resource inject error", e); + return null; + } + } + + @Override + public Type resourceType() { + return ResourceFactory.class; + } + + @Override + public boolean autoNone() { + return false; + } + }); + this.resourceFactory.register(new ResourceTypeLoader() { + + @Override + public Object load(ResourceFactory rf, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment) { + try { + NodeServer server = null; + for (NodeServer ns : application.getNodeServers()) { + if (ns.getClass() != NodeSncpServer.class) { + continue; + } + if (resourceName.equals(ns.server.getName())) { + server = ns; + break; + } + } + field.set(srcObj, server); + return server; + } catch (Exception e) { + logger.log(Level.SEVERE, "Resource inject error", e); + return null; + } + } + + @Override + public Type resourceType() { + return NodeSncpServer.class; + } + + @Override + public boolean autoNone() { + return false; + } + }); + this.resourceFactory.register(new ResourceTypeLoader() { + + @Override + public Object load(ResourceFactory rf, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment) { + try { + NodeServer server = null; + for (NodeServer ns : application.getNodeServers()) { + if (ns.getClass() != NodeHttpServer.class) { + continue; + } + if (resourceName.equals(ns.server.getName())) { + server = ns; + break; + } + } + field.set(srcObj, server); + return server; + } catch (Exception e) { + logger.log(Level.SEVERE, "Resource inject error", e); + return null; + } + } + + @Override + public Type resourceType() { + return NodeHttpServer.class; + } + + @Override + public boolean autoNone() { + return false; + } + }); + this.resourceFactory.register(new ResourceTypeLoader() { + + @Override + public Object load(ResourceFactory rf, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment) { + try { + NodeServer server = null; + for (NodeServer ns : application.getNodeServers()) { + if (ns.getClass() != NodeWatchServer.class) { + continue; + } + if (resourceName.equals(ns.server.getName())) { + server = ns; + break; + } + } + field.set(srcObj, server); + return server; + } catch (Exception e) { + logger.log(Level.SEVERE, "Resource inject error", e); + return null; + } + } + + @Override + public Type resourceType() { + return NodeWatchServer.class; + } + + @Override + public boolean autoNone() { + return false; + } + }); //------------------------------------ 注册 java.net.http.HttpClient ------------------------------------ - resourceFactory.register((ResourceFactory rf, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment) -> { - try { - java.net.http.HttpClient.Builder builder = java.net.http.HttpClient.newBuilder(); - if (resourceName.endsWith(".1.1")) { - builder.version(HttpClient.Version.HTTP_1_1); - } else if (resourceName.endsWith(".2")) { - builder.version(HttpClient.Version.HTTP_2); + resourceFactory.register(new ResourceTypeLoader() { + + @Override + public Object load(ResourceFactory rf, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment) { + try { + java.net.http.HttpClient.Builder builder = java.net.http.HttpClient.newBuilder(); + if (resourceName.endsWith(".1.1")) { + builder.version(HttpClient.Version.HTTP_1_1); + } else if (resourceName.endsWith(".2")) { + builder.version(HttpClient.Version.HTTP_2); + } + java.net.http.HttpClient httpClient = builder.build(); + field.set(srcObj, httpClient); + rf.inject(resourceName, httpClient, null); // 给其可能包含@Resource的字段赋值; + rf.register(resourceName, java.net.http.HttpClient.class, httpClient); + return httpClient; + } catch (Exception e) { + logger.log(Level.SEVERE, java.net.http.HttpClient.class.getSimpleName() + " inject error", e); + return null; } - java.net.http.HttpClient httpClient = builder.build(); - field.set(srcObj, httpClient); - rf.inject(resourceName, httpClient, null); // 给其可能包含@Resource的字段赋值; - rf.register(resourceName, java.net.http.HttpClient.class, httpClient); - return httpClient; - } catch (Exception e) { - logger.log(Level.SEVERE, java.net.http.HttpClient.class.getSimpleName() + " inject error", e); - return null; } - }, java.net.http.HttpClient.class); + + @Override + public Type resourceType() { + return java.net.http.HttpClient.class; + } + }); //------------------------------------ 注册 WebClient ------------------------------------ - resourceFactory.register((ResourceFactory rf, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment) -> { - try { - WebClient httpClient = WebClient.create(workExecutor, clientAsyncGroup); - field.set(srcObj, httpClient); - rf.inject(resourceName, httpClient, null); // 给其可能包含@Resource的字段赋值; - rf.register(resourceName, WebClient.class, httpClient); - return httpClient; - } catch (Exception e) { - logger.log(Level.SEVERE, WebClient.class.getSimpleName() + " inject error", e); - return null; + resourceFactory.register(new ResourceTypeLoader() { + + @Override + public Object load(ResourceFactory rf, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment) { + try { + WebClient httpClient = WebClient.create(workExecutor, clientAsyncGroup); + field.set(srcObj, httpClient); + rf.inject(resourceName, httpClient, null); // 给其可能包含@Resource的字段赋值; + rf.register(resourceName, WebClient.class, httpClient); + return httpClient; + } catch (Exception e) { + logger.log(Level.SEVERE, WebClient.class.getSimpleName() + " inject error", e); + return null; + } } - }, WebClient.class); + + @Override + public Type resourceType() { + return WebClient.class; + } + }); //------------------------------------ 注册 HttpRpcClient ------------------------------------ - resourceFactory.register((ResourceFactory rf, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment) -> { - try { - ClusterAgent clusterAgent = resourceFactory.find("", ClusterAgent.class); - MessageAgent messageAgent = resourceFactory.find(resourceName, MessageAgent.class); - if (messageAgent != null) { - if (clusterAgent == null || !Objects.equals(clusterAgent.getName(), resourceName) - || messageAgent.isRpcFirst()) { - HttpRpcClient rpcClient = messageAgent.getHttpRpcClient(); + resourceFactory.register(new ResourceTypeLoader() { + + @Override + public Object load(ResourceFactory rf, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment) { + try { + ClusterAgent clusterAgent = resourceFactory.find("", ClusterAgent.class); + MessageAgent messageAgent = resourceFactory.find(resourceName, MessageAgent.class); + if (messageAgent != null) { + if (clusterAgent == null || !Objects.equals(clusterAgent.getName(), resourceName) + || messageAgent.isRpcFirst()) { + HttpRpcClient rpcClient = messageAgent.getHttpRpcClient(); + field.set(srcObj, rpcClient); + rf.inject(resourceName, rpcClient, null); // 给其可能包含@Resource的字段赋值; + rf.register(resourceName, HttpRpcClient.class, rpcClient); + return rpcClient; + } + } + if (clusterAgent == null) { + HttpRpcClient rpcClient = new HttpLocalRpcClient(application, resourceName); field.set(srcObj, rpcClient); rf.inject(resourceName, rpcClient, null); // 给其可能包含@Resource的字段赋值; rf.register(resourceName, HttpRpcClient.class, rpcClient); return rpcClient; } - } - if (clusterAgent == null) { - HttpRpcClient rpcClient = new HttpLocalRpcClient(application, resourceName); + HttpRpcClient rpcClient = new HttpClusterRpcClient(application, resourceName, clusterAgent); field.set(srcObj, rpcClient); rf.inject(resourceName, rpcClient, null); // 给其可能包含@Resource的字段赋值; rf.register(resourceName, HttpRpcClient.class, rpcClient); return rpcClient; + } catch (Exception e) { + logger.log(Level.SEVERE, HttpRpcClient.class.getSimpleName() + " inject error", e); + return null; } - HttpRpcClient rpcClient = new HttpClusterRpcClient(application, resourceName, clusterAgent); - field.set(srcObj, rpcClient); - rf.inject(resourceName, rpcClient, null); // 给其可能包含@Resource的字段赋值; - rf.register(resourceName, HttpRpcClient.class, rpcClient); - return rpcClient; - } catch (Exception e) { - logger.log(Level.SEVERE, HttpRpcClient.class.getSimpleName() + " inject error", e); - return null; } - }, HttpRpcClient.class); + + @Override + public Type resourceType() { + return HttpRpcClient.class; + } + }); } private void registerResourceEnvs(boolean first, Properties... envs) { diff --git a/src/main/java/org/redkale/boot/NodeHttpServer.java b/src/main/java/org/redkale/boot/NodeHttpServer.java index 987207614..6a31b3627 100644 --- a/src/main/java/org/redkale/boot/NodeHttpServer.java +++ b/src/main/java/org/redkale/boot/NodeHttpServer.java @@ -127,64 +127,73 @@ public class NodeHttpServer extends NodeServer { private void initWebSocketService() { final NodeServer self = this; final ResourceFactory regFactory = application.getResourceFactory(); - resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, Object attachment) -> { //主要用于单点的服务 - try { - if (!(srcObj instanceof WebSocketServlet)) { + resourceFactory.register(new ResourceTypeLoader() { + + @Override + public Object load(ResourceFactory rf, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment) { //主要用于单点的服务 + try { + if (!(srcObj instanceof WebSocketServlet)) { + return null; + } + ResourceTypeLoader loader = null; + ResourceFactory sncpResFactory = null; + for (NodeServer ns : application.servers) { + if (!ns.isSNCP()) { + continue; + } + sncpResFactory = ns.resourceFactory; + loader = sncpResFactory.findTypeLoader(WebSocketNode.class, field); + if (loader != null) { + break; + } + } + Service nodeService = null; + if (loader != null) { + nodeService = (Service) loader.load(sncpResFactory, srcResourceName, srcObj, resourceName, field, attachment); + } + regFactory.lock(); + try { + if (nodeService == null) { + nodeService = (Service) rf.find(resourceName, WebSocketNode.class); + } + if (sncpResFactory != null && resourceFactory.find(RESNAME_SNCP_ADDRESS, String.class) == null) { + resourceFactory.register(RESNAME_SNCP_ADDRESS, InetSocketAddress.class, sncpResFactory.find(RESNAME_SNCP_ADDRESS, InetSocketAddress.class)); + resourceFactory.register(RESNAME_SNCP_ADDRESS, SocketAddress.class, sncpResFactory.find(RESNAME_SNCP_ADDRESS, SocketAddress.class)); + resourceFactory.register(RESNAME_SNCP_ADDRESS, String.class, sncpResFactory.find(RESNAME_SNCP_ADDRESS, String.class)); + } + if (nodeService == null) { + MessageAgent messageAgent = null; + try { + Field c = WebSocketServlet.class.getDeclaredField("messageAgent"); + RedkaleClassLoader.putReflectionField("messageAgent", c); + c.setAccessible(true); + messageAgent = (MessageAgent) c.get(srcObj); + } catch (Exception ex) { + logger.log(Level.WARNING, "WebSocketServlet getMessageAgent error", ex); + } + AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, WebSocketNodeService.class); + nodeService = Sncp.createLocalService(serverClassLoader, resourceName, WebSocketNodeService.class, methodBoost, + application.getResourceFactory(), application.getSncpRpcGroups(), sncpClient, messageAgent, (String) null, (AnyValue) null); + regFactory.register(resourceName, WebSocketNode.class, nodeService); + } + resourceFactory.inject(resourceName, nodeService, self); + field.set(srcObj, nodeService); + logger.fine("Load Service " + nodeService); + return nodeService; + } finally { + regFactory.unlock(); + } + } catch (Exception e) { + logger.log(Level.SEVERE, "WebSocketNode inject error", e); return null; } - ResourceTypeLoader loader = null; - ResourceFactory sncpResFactory = null; - for (NodeServer ns : application.servers) { - if (!ns.isSNCP()) { - continue; - } - sncpResFactory = ns.resourceFactory; - loader = sncpResFactory.findTypeLoader(WebSocketNode.class, field); - if (loader != null) { - break; - } - } - Service nodeService = null; - if (loader != null) { - nodeService = (Service) loader.load(sncpResFactory, srcResourceName, srcObj, resourceName, field, attachment); - } - regFactory.lock(); - try { - if (nodeService == null) { - nodeService = (Service) rf.find(resourceName, WebSocketNode.class); - } - if (sncpResFactory != null && resourceFactory.find(RESNAME_SNCP_ADDRESS, String.class) == null) { - resourceFactory.register(RESNAME_SNCP_ADDRESS, InetSocketAddress.class, sncpResFactory.find(RESNAME_SNCP_ADDRESS, InetSocketAddress.class)); - resourceFactory.register(RESNAME_SNCP_ADDRESS, SocketAddress.class, sncpResFactory.find(RESNAME_SNCP_ADDRESS, SocketAddress.class)); - resourceFactory.register(RESNAME_SNCP_ADDRESS, String.class, sncpResFactory.find(RESNAME_SNCP_ADDRESS, String.class)); - } - if (nodeService == null) { - MessageAgent messageAgent = null; - try { - Field c = WebSocketServlet.class.getDeclaredField("messageAgent"); - RedkaleClassLoader.putReflectionField("messageAgent", c); - c.setAccessible(true); - messageAgent = (MessageAgent) c.get(srcObj); - } catch (Exception ex) { - logger.log(Level.WARNING, "WebSocketServlet getMessageAgent error", ex); - } - AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, WebSocketNodeService.class); - nodeService = Sncp.createLocalService(serverClassLoader, resourceName, WebSocketNodeService.class, methodBoost, - application.getResourceFactory(), application.getSncpRpcGroups(), sncpClient, messageAgent, (String) null, (AnyValue) null); - regFactory.register(resourceName, WebSocketNode.class, nodeService); - } - resourceFactory.inject(resourceName, nodeService, self); - field.set(srcObj, nodeService); - logger.fine("Load Service " + nodeService); - return nodeService; - } finally { - regFactory.unlock(); - } - } catch (Exception e) { - logger.log(Level.SEVERE, "WebSocketNode inject error", e); - return null; } - }, WebSocketNode.class); + + @Override + public Type resourceType() { + return WebSocketNode.class; + } + }); } @SuppressWarnings("unchecked") diff --git a/src/main/java/org/redkale/boot/NodeServer.java b/src/main/java/org/redkale/boot/NodeServer.java index b3f36655a..2017dc5fa 100644 --- a/src/main/java/org/redkale/boot/NodeServer.java +++ b/src/main/java/org/redkale/boot/NodeServer.java @@ -250,7 +250,17 @@ public abstract class NodeServer { private void registerResTypeLoader() { //--------------------- 注册 Local AutoLoad(false) Service --------------------- - resourceFactory.register(this::loadResourceService, Service.class); + resourceFactory.register(new ResourceTypeLoader() { + @Override + public Object load(ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, final Object attachment) { + return loadResourceService(rf, srcResourceName, srcObj, resourceName, field, attachment); + } + + @Override + public Type resourceType() { + return Service.class; + } + }); //----------------------------- 注册 WebSocketNode ----------------------------- final NodeServer self = this; final ResourceFactory appResFactory = application.getResourceFactory(); @@ -291,11 +301,16 @@ public abstract class NodeServer { } } + @Override + public Type resourceType() { + return WebSocketNode.class; + } + @Override public boolean autoNone() { return false; } - }, WebSocketNode.class); + }); } //Service.class的ResourceTypeLoader @@ -354,13 +369,107 @@ public abstract class NodeServer { } } + private class ExpectServiceLoader implements ResourceTypeLoader { + + private final Class type; + + private final Class serviceImplClass; + + private final AtomicInteger serviceCount; + + private final SncpRpcGroups rpcGroups; + + private final FilterEntry entry; + + private final String group; + + private final boolean localMode; + + public ExpectServiceLoader(Class type, Class serviceImplClass, AtomicInteger serviceCount, + SncpRpcGroups rpcGroups, FilterEntry entry, String group, boolean localMode) { + this.type = type; + this.serviceImplClass = serviceImplClass; + this.serviceCount = serviceCount; + this.rpcGroups = rpcGroups; + this.entry = entry; + this.group = group; + this.localMode = localMode; + } + + @Override + public Object load(ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, final Object attachment) { + try { + final ResourceFactory appResourceFactory = application.getResourceFactory(); + ResourceFactory regFactory = isSNCP() ? application.getResourceFactory() : resourceFactory; + + if (Sncp.loadRemoteMethodActions(Sncp.getResourceType(serviceImplClass)).isEmpty() + && (serviceImplClass.getAnnotation(Priority.class) == null + && serviceImplClass.getAnnotation(javax.annotation.Priority.class) == null)) { //class没有可用的方法且没有标记启动优先级的, 通常为BaseService + if (!serviceImplClass.getName().startsWith("org.redkale.") && !serviceImplClass.getSimpleName().contains("Base")) { + logger.log(Level.FINE, serviceImplClass + " cannot load because not found less one public non-final method"); + } + return null; + } + RedkaleClassLoader.putReflectionPublicMethods(serviceImplClass.getName()); + MessageAgent mqAgent = getMessageAgent(entry.getProperty()); + Service service; + if (Sncp.isComponent(serviceImplClass)) { //Component + RedkaleClassLoader.putReflectionPublicConstructors(serviceImplClass, serviceImplClass.getName()); + if (!acceptsComponent(serviceImplClass)) { + return null; + } + service = serviceImplClass.getDeclaredConstructor().newInstance(); + } else if (srcObj instanceof WebSocketServlet || localMode) { //本地模式 + AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, serviceImplClass); + service = Sncp.createLocalService(serverClassLoader, resourceName, serviceImplClass, + methodBoost, appResourceFactory, rpcGroups, sncpClient, mqAgent, group, entry.getProperty()); + } else { + AsmMethodBoost methodBoost = application.createAsmMethodBoost(true, serviceImplClass); + service = Sncp.createRemoteService(serverClassLoader, resourceName, serviceImplClass, + methodBoost, appResourceFactory, rpcGroups, sncpClient, mqAgent, group, entry.getProperty()); + } + final Class restype = Sncp.getResourceType(service); + if (rf.find(resourceName, restype) == null) { + regFactory.register(resourceName, restype, service); + } else if (isSNCP() && !entry.isAutoload()) { + throw new RedkaleException(restype.getSimpleName() + + "(class:" + serviceImplClass.getName() + ", name:" + resourceName + ", group:" + group + ") is repeat."); + } + if (Sncp.isRemote(service)) { + remoteServices.add(service); + if (mqAgent != null) { + sncpRemoteAgents.put(mqAgent.getName(), mqAgent); + } + } else { + if (field != null) { + rf.inject(resourceName, service); //动态加载的Service也存在按需加载的注入资源 + } + localServices.add(service); + if (!Sncp.isComponent(service)) { + servletServices.add(service); + } + } + serviceCount.incrementAndGet(); + return service; + } catch (RuntimeException ex) { + throw ex; + } catch (Exception e) { + throw new RedkaleException(e); + } + } + + @Override + public Type resourceType() { + return type; + } + + } + @SuppressWarnings("unchecked") protected void loadService(ClassFilter serviceFilter) throws Exception { Objects.requireNonNull(serviceFilter); final long starts = System.currentTimeMillis(); final Set> entrys = (Set) serviceFilter.getAllFilterEntrys(); - ResourceFactory regFactory = isSNCP() ? application.getResourceFactory() : resourceFactory; - final ResourceFactory appResourceFactory = application.getResourceFactory(); final SncpRpcGroups rpcGroups = application.getSncpRpcGroups(); final AtomicInteger serviceCount = new AtomicInteger(); for (FilterEntry entry : entrys) { //service实现类 @@ -406,71 +515,14 @@ public abstract class NodeServer { if ((localMode || Sncp.isComponent(serviceImplClass)) && Utility.isAbstractOrInterface(serviceImplClass)) { continue; //本地模式或Component不能实例化接口和抽象类的Service类 } - - final ResourceTypeLoader resourceLoader = (ResourceFactory rf, String srcResourceName, - final Object srcObj, final String resourceName, Field field, final Object attachment) -> { - try { - if (Sncp.loadRemoteMethodActions(Sncp.getResourceType(serviceImplClass)).isEmpty() - && (serviceImplClass.getAnnotation(Priority.class) == null - && serviceImplClass.getAnnotation(javax.annotation.Priority.class) == null)) { //class没有可用的方法且没有标记启动优先级的, 通常为BaseService - if (!serviceImplClass.getName().startsWith("org.redkale.") && !serviceImplClass.getSimpleName().contains("Base")) { - logger.log(Level.FINE, serviceImplClass + " cannot load because not found less one public non-final method"); - } - return null; - } - RedkaleClassLoader.putReflectionPublicMethods(serviceImplClass.getName()); - MessageAgent mqAgent = getMessageAgent(entry.getProperty()); - Service service; - if (Sncp.isComponent(serviceImplClass)) { //Component - RedkaleClassLoader.putReflectionPublicConstructors(serviceImplClass, serviceImplClass.getName()); - if (!acceptsComponent(serviceImplClass)) { - return null; - } - service = serviceImplClass.getDeclaredConstructor().newInstance(); - } else if (srcObj instanceof WebSocketServlet || localMode) { //本地模式 - AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, serviceImplClass); - service = Sncp.createLocalService(serverClassLoader, resourceName, serviceImplClass, - methodBoost, appResourceFactory, rpcGroups, this.sncpClient, mqAgent, group, entry.getProperty()); - } else { - AsmMethodBoost methodBoost = application.createAsmMethodBoost(true, serviceImplClass); - service = Sncp.createRemoteService(serverClassLoader, resourceName, serviceImplClass, - methodBoost, appResourceFactory, rpcGroups, this.sncpClient, mqAgent, group, entry.getProperty()); - } - final Class restype = Sncp.getResourceType(service); - if (rf.find(resourceName, restype) == null) { - regFactory.register(resourceName, restype, service); - } else if (isSNCP() && !entry.isAutoload()) { - throw new RedkaleException(restype.getSimpleName() - + "(class:" + serviceImplClass.getName() + ", name:" + resourceName + ", group:" + group + ") is repeat."); - } - if (Sncp.isRemote(service)) { - remoteServices.add(service); - if (mqAgent != null) { - sncpRemoteAgents.put(mqAgent.getName(), mqAgent); - } - } else { - if (field != null) { - rf.inject(resourceName, service); //动态加载的Service也存在按需加载的注入资源 - } - localServices.add(service); - if (!Sncp.isComponent(service)) { - servletServices.add(service); - } - } - serviceCount.incrementAndGet(); - return service; - } catch (RuntimeException ex) { - throw ex; - } catch (Exception e) { - throw new RedkaleException(e); - } - }; if (entry.isExpect()) { Class t = ResourceFactory.getResourceType(entry.getType()); if (resourceFactory.findResourceTypeLoader(t) == null) { - resourceFactory.register(resourceLoader, t); + resourceFactory.register(new ExpectServiceLoader(t, serviceImplClass, serviceCount, rpcGroups, entry, group, localMode)); } } else { + ExpectServiceLoader resourceLoader = new ExpectServiceLoader(serviceImplClass, + serviceImplClass, serviceCount, rpcGroups, entry, group, localMode); resourceLoader.load(resourceFactory, null, null, entry.getName(), null, false); } diff --git a/src/main/java/org/redkale/inject/ResourceFactory.java b/src/main/java/org/redkale/inject/ResourceFactory.java index 45bed8bf4..949d5c8cc 100644 --- a/src/main/java/org/redkale/inject/ResourceFactory.java +++ b/src/main/java/org/redkale/inject/ResourceFactory.java @@ -1056,13 +1056,8 @@ public final class ResourceFactory { parentRoot().resAnnotationLoaderMap.put(loader.annotationType(), loader); } - public void register(final ResourceTypeLoader rs, final Type... clazzs) { - if (clazzs == null || rs == null) { - return; - } - for (Type clazz : clazzs) { - resTypeLoaderMap.put(clazz, rs); - } + public void register(final ResourceTypeLoader rs) { + resTypeLoaderMap.put(rs.resourceType(), rs); } public ResourceTypeLoader findResourceTypeLoader(Type clazz) { diff --git a/src/main/java/org/redkale/inject/ResourceTypeLoader.java b/src/main/java/org/redkale/inject/ResourceTypeLoader.java index 4af256db2..6d910674c 100644 --- a/src/main/java/org/redkale/inject/ResourceTypeLoader.java +++ b/src/main/java/org/redkale/inject/ResourceTypeLoader.java @@ -3,6 +3,7 @@ package org.redkale.inject; import java.lang.reflect.Field; +import java.lang.reflect.Type; /** * 自定义注入加载器 @@ -16,6 +17,8 @@ public interface ResourceTypeLoader { public Object load(ResourceFactory factory, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment); + public Type resourceType(); + //返回true: 表示调用ResourceLoader之后资源仍不存在,则会在ResourceFactory里注入默认值null。 //返回false: 表示资源不存在下次仍会调用ResourceLoader自行处理。 default boolean autoNone() { diff --git a/src/main/java/org/redkale/mq/spi/MessageModuleEngine.java b/src/main/java/org/redkale/mq/spi/MessageModuleEngine.java index 35e807a1b..062bb2efa 100644 --- a/src/main/java/org/redkale/mq/spi/MessageModuleEngine.java +++ b/src/main/java/org/redkale/mq/spi/MessageModuleEngine.java @@ -4,6 +4,7 @@ package org.redkale.mq.spi; import java.lang.reflect.Field; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; @@ -370,7 +371,7 @@ public class MessageModuleEngine extends ModuleEngine { } serResourceFactory.register(new ResourceTypeLoader() { @Override - public Object load(ResourceFactory factory, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment) { + public Object load(ResourceFactory rf, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment) { for (ResourceFactory f : factorys) { Object val = f.find(resourceName, field.getGenericType()); if (val != null) { @@ -380,11 +381,16 @@ public class MessageModuleEngine extends ModuleEngine { return null; } + @Override + public Type resourceType() { + return Object.class; + } + @Override public boolean autoNone() { return false; } - }, Object.class); + }); for (MessageAgent agent : this.messageAgents) { names.add(agent.getName()); List consumers = agentConsumers.getOrDefault(agent.getName(), new CopyOnWriteArrayList<>()); diff --git a/src/main/java/org/redkale/source/FilterNode.java b/src/main/java/org/redkale/source/FilterNode.java index eace8ba25..7aff35e33 100644 --- a/src/main/java/org/redkale/source/FilterNode.java +++ b/src/main/java/org/redkale/source/FilterNode.java @@ -892,8 +892,8 @@ public class FilterNode { //FilterNode 不能实现Serializable接口, 否则 if (!items) { if (val0.getClass().isArray()) { Class comp = val0.getClass().getComponentType(); - if (comp == java.io.Serializable.class) { - comp = ((Object[]) val0)[0].getClass(); + if (Array.getLength(val0) > 0) { + comp = Array.get(val0, 0).getClass(); } if (!(comp.isPrimitive() || CharSequence.class.isAssignableFrom(comp) || Number.class.isAssignableFrom(comp))) { items = true; diff --git a/src/main/java/org/redkale/source/spi/SourceModuleEngine.java b/src/main/java/org/redkale/source/spi/SourceModuleEngine.java index 3fe6b5122..8747e000d 100644 --- a/src/main/java/org/redkale/source/spi/SourceModuleEngine.java +++ b/src/main/java/org/redkale/source/spi/SourceModuleEngine.java @@ -4,6 +4,7 @@ package org.redkale.source.spi; import java.lang.reflect.Field; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -135,9 +136,9 @@ public class SourceModuleEngine extends ModuleEngine implements SourceManager { } resourceFactory.register(SourceManager.class, this); //--------------------------------- 注册 DataSource、CacheSource --------------------------------- - resourceFactory.register(new DataSourceLoader(), DataSource.class); - resourceFactory.register(new CacheSourceLoader(), CacheSource.class); - resourceFactory.register(new DataSqlMapperLoader(), DataSqlMapper.class); + resourceFactory.register(new DataSourceLoader()); + resourceFactory.register(new CacheSourceLoader()); + resourceFactory.register(new DataSqlMapperLoader()); } /** @@ -538,6 +539,11 @@ public class SourceModuleEngine extends ModuleEngine implements SourceManager { return null; } } + + @Override + public Type resourceType() { + return DataSqlMapper.class; + } } private class DataSourceLoader implements ResourceTypeLoader { @@ -556,6 +562,11 @@ public class SourceModuleEngine extends ModuleEngine implements SourceManager { return null; } } + + @Override + public Type resourceType() { + return DataSource.class; + } } private class CacheSourceLoader implements ResourceTypeLoader { @@ -585,6 +596,11 @@ public class SourceModuleEngine extends ModuleEngine implements SourceManager { } } + @Override + public Type resourceType() { + return CacheSource.class; + } + @Override public boolean autoNone() { return false;