From 4a91e6eb18ac72fa880d1e756bcf034b68581243 Mon Sep 17 00:00:00 2001 From: Redkale Date: Sun, 11 Dec 2022 21:37:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BA=9F=E5=BC=83=E4=BE=9D=E8=B5=96=E6=B3=A8?= =?UTF-8?q?=E5=85=A5=E9=85=8D=E7=BD=AE=E9=A1=B9=E6=97=B6=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8A=A0=E5=85=A5"property."=E5=89=8D=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/redkale/boot/Application.java | 61 ++++++------ .../java/org/redkale/boot/NodeHttpServer.java | 6 +- .../java/org/redkale/boot/NodeServer.java | 45 +++++---- .../redkale/mq/HttpMessageClusterClient.java | 4 +- src/main/java/org/redkale/net/Server.java | 2 +- .../org/redkale/net/http/WebSocketNode.java | 6 +- .../redkale/net/http/WebSocketServlet.java | 11 ++- .../org/redkale/source/CacheMemorySource.java | 2 +- .../org/redkale/util/ResourceFactory.java | 93 +++++++++++-------- .../org/redkale/util/ResourceTypeLoader.java | 2 +- .../test/util/ResourceListenerTest.java | 6 +- .../org/redkale/test/util/ResourceTest.java | 8 +- 12 files changed, 135 insertions(+), 111 deletions(-) diff --git a/src/main/java/org/redkale/boot/Application.java b/src/main/java/org/redkale/boot/Application.java index 5272c13c8..b2f62eb44 100644 --- a/src/main/java/org/redkale/boot/Application.java +++ b/src/main/java/org/redkale/boot/Application.java @@ -124,7 +124,7 @@ public final class Application { /** * 当前Server的ResourceFactory */ - public static final String RESNAME_SERVER_RESFACTORY = Server.RESNAME_SERVER_RESFACTORY; + public static final String RESNAME_SERVER_RESFACTORY = "SERVER_RESFACTORY"; private static final int UDP_CAPACITY = 1024; @@ -682,10 +682,10 @@ public final class Application { in.close(); if (logger.isLoggable(Level.FINEST)) logger.log(Level.FINEST, "load properties(" + dfload + ") size = " + ps.size()); ps.forEach((x, y) -> { //load中的配置项除了redkale.cachesource.和redkale.datasource.开头,不应该有其他redkale.开头配置项 - if (!x.toString().startsWith("redkale.") && !x.toString().startsWith("property.")) { + if (!x.toString().startsWith("redkale.")) { agentEnvs.put(x, y); } else { - logger.log(Level.WARNING, "skip illegal(startswith redkale. or property.) key " + x + " in properties file"); + logger.log(Level.WARNING, "skip illegal(startswith 'redkale.') key " + x + " in properties file"); } }); } catch (Exception e) { @@ -737,17 +737,11 @@ public final class Application { String key = prop.getValue("name"); String value = prop.getValue("value"); if (key == null || value == null) continue; - if (key.startsWith("property.")) { - logger.log(Level.WARNING, "property key (" + key + ") startswith 'property.' is illegal, auto remove the prefix 'property.'"); - key = key.substring("property.".length()); - } oldEnvs.put(key, value); } agentEnvs.forEach((k, v) -> { if (k.toString().startsWith("redkale.")) { dyncProps.put(k, v); - } else if (k.toString().startsWith("property.")) { - logger.log(Level.WARNING, "skip illegal(startswith property.) key " + k + " in remote properties agent"); } else { oldEnvs.put(k, v); //新配置项会覆盖旧的 } @@ -830,12 +824,9 @@ public final class Application { } } else if (key.startsWith("mimetype.property.")) { MimeType.add(key.substring("mimetype.property.".length()), value); - } else if (key.startsWith("property.")) { - this.envProperties.put(key, value); - resourceFactory.register(key, value); } else { this.envProperties.put(key, value); - resourceFactory.register(false, "property." + key, value); + resourceFactory.register(false, key, value); } } } @@ -987,19 +978,23 @@ public final class Application { this.resourceFactory.register(new ResourceTypeLoader() { @Override - public void load(ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) { + public Object load(ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) { try { Resource res = field.getAnnotation(Resource.class); - if (res == null) return; - if (srcObj instanceof Service && Sncp.isRemote((Service) srcObj)) return; //远程模式不得注入 + if (res == null) return null; + if (srcObj instanceof Service && Sncp.isRemote((Service) srcObj)) return null; //远程模式不得注入 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(res.name()) || res.name().equalsIgnoreCase("server"); - field.set(srcObj, serv ? rf : (res.name().isEmpty() ? application.resourceFactory : null)); + ResourceFactory rs = serv ? rf : (res.name().isEmpty() ? application.resourceFactory : null); + field.set(srcObj, rs); + return rs; } else if (type == TransportFactory.class) { field.set(srcObj, application.sncpTransportFactory); + return application.sncpTransportFactory; } else if (type == NodeSncpServer.class) { NodeServer server = null; for (NodeServer ns : application.getNodeServers()) { @@ -1010,6 +1005,7 @@ public final class Application { } } field.set(srcObj, server); + return server; } else if (type == NodeHttpServer.class) { NodeServer server = null; for (NodeServer ns : application.getNodeServers()) { @@ -1020,6 +1016,7 @@ public final class Application { } } field.set(srcObj, server); + return server; } else if (type == NodeWatchServer.class) { NodeServer server = null; for (NodeServer ns : application.getNodeServers()) { @@ -1030,12 +1027,15 @@ public final class Application { } } field.set(srcObj, server); + return server; } // if (type == WatchFactory.class) { // field.set(src, application.watchFactory); // } + return null; } catch (Exception e) { logger.log(Level.SEVERE, "Resource inject error", e); + return null; } } @@ -1049,7 +1049,7 @@ public final class Application { //------------------------------------ 注册 java.net.http.HttpClient ------------------------------------ resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> { try { - if (field.getAnnotation(Resource.class) == null) return; + if (field.getAnnotation(Resource.class) == null) return null; java.net.http.HttpClient.Builder builder = java.net.http.HttpClient.newBuilder(); if (resourceName.endsWith(".1.1")) { builder.version(HttpClient.Version.HTTP_1_1); @@ -1060,20 +1060,24 @@ public final class Application { 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, "[" + Thread.currentThread().getName() + "] java.net.http.HttpClient inject error", e); + return null; } }, java.net.http.HttpClient.class); //------------------------------------ 注册 HttpSimpleClient ------------------------------------ resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> { try { - if (field.getAnnotation(Resource.class) == null) return; + if (field.getAnnotation(Resource.class) == null) return null; HttpSimpleClient httpClient = HttpSimpleClient.create(clientAsyncGroup); field.set(srcObj, httpClient); rf.inject(resourceName, httpClient, null); // 给其可能包含@Resource的字段赋值; rf.register(resourceName, HttpSimpleClient.class, httpClient); + return httpClient; } catch (Exception e) { logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] HttpClient inject error", e); + return null; } }, HttpSimpleClient.class); //-------------------------------------------------------------------------- @@ -1108,20 +1112,22 @@ public final class Application { //------------------------------------ 注册 HttpMessageClient ------------------------------------ resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> { try { - if (field.getAnnotation(Resource.class) == null) return; + if (field.getAnnotation(Resource.class) == null) return null; if (clusterAgent == null) { HttpMessageClient messageClient = new HttpMessageLocalClient(application, resourceName); field.set(srcObj, messageClient); rf.inject(resourceName, messageClient, null); // 给其可能包含@Resource的字段赋值; rf.register(resourceName, HttpMessageClient.class, messageClient); - return; + return messageClient; } HttpMessageClient messageClient = new HttpMessageClusterClient(application, resourceName, clusterAgent); field.set(srcObj, messageClient); rf.inject(resourceName, messageClient, null); // 给其可能包含@Resource的字段赋值; rf.register(resourceName, HttpMessageClient.class, messageClient); + return messageClient; } catch (Exception e) { logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] HttpMessageClient inject error", e); + return null; } }, HttpMessageClient.class); initResources(); @@ -1943,22 +1949,11 @@ public final class Application { if (event.newValue() != null) { MimeType.add(propName, event.newValue()); } - } else if (event.name().startsWith("property.")) { - if (!Objects.equals(event.newValue(), this.envProperties.getProperty(event.name()))) { - envRegisterProps.put(event.name(), event.newValue()); - if (event.newValue() == null) { - if (this.envProperties.containsKey(event.name())) { - envRemovedKeys.add(event.name()); - } - } else { - envChangedProps.put(event.name(), event.newValue()); - } - } } else if (event.name().startsWith("redkale.")) { logger.log(Level.WARNING, "not support the environment property key " + event.name() + " on change event"); } else { if (!Objects.equals(event.newValue(), this.envProperties.getProperty(event.name()))) { - envRegisterProps.put("property." + event.name(), event.newValue()); + envRegisterProps.put(event.name(), event.newValue()); if (event.newValue() == null) { if (this.envProperties.containsKey(event.name())) { envRemovedKeys.add(event.name()); diff --git a/src/main/java/org/redkale/boot/NodeHttpServer.java b/src/main/java/org/redkale/boot/NodeHttpServer.java index 1e56c7f6c..9dd477743 100644 --- a/src/main/java/org/redkale/boot/NodeHttpServer.java +++ b/src/main/java/org/redkale/boot/NodeHttpServer.java @@ -104,8 +104,8 @@ public class NodeHttpServer extends NodeServer { final ResourceFactory regFactory = application.getResourceFactory(); resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, Object attachment) -> { //主要用于单点的服务 try { - if (field.getAnnotation(Resource.class) == null) return; - if (!(srcObj instanceof WebSocketServlet)) return; + if (field.getAnnotation(Resource.class) == null) return null; + if (!(srcObj instanceof WebSocketServlet)) return null; ResourceTypeLoader loader = null; ResourceFactory sncpResFactory = null; for (NodeServer ns : application.servers) { @@ -137,9 +137,11 @@ public class NodeHttpServer extends NodeServer { resourceFactory.inject(resourceName, nodeService, self); field.set(srcObj, nodeService); logger.fine("[" + Thread.currentThread().getName() + "] Load Service " + nodeService); + return nodeService; } } catch (Exception e) { logger.log(Level.SEVERE, "WebSocketNode inject error", e); + return null; } }, WebSocketNode.class); } diff --git a/src/main/java/org/redkale/boot/NodeServer.java b/src/main/java/org/redkale/boot/NodeServer.java index e7797a098..0d4cdefb1 100644 --- a/src/main/java/org/redkale/boot/NodeServer.java +++ b/src/main/java/org/redkale/boot/NodeServer.java @@ -216,10 +216,10 @@ public abstract class NodeServer { resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> { try { Resource res = field.getAnnotation(Resource.class); - if (res == null || !res.name().startsWith("properties.")) return; - if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return; //远程模式不得注入 DataSource + if (res == null || !res.name().startsWith("properties.")) return null; + if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return null; //远程模式不得注入 DataSource Class type = field.getType(); - if (type != AnyValue.class && type != AnyValue[].class) return; + if (type != AnyValue.class && type != AnyValue[].class) return null; Object resource = null; final AnyValue properties = application.getAppConfig().getAnyValue("properties"); if (properties != null && type == AnyValue.class) { @@ -230,8 +230,10 @@ public abstract class NodeServer { appResFactory.register(resourceName, AnyValue[].class, resource); } field.set(srcObj, resource); + return resource; } catch (Exception e) { logger.log(Level.SEVERE, "Resource inject error", e); + return null; } }, AnyValue.class, AnyValue[].class); @@ -239,13 +241,13 @@ public abstract class NodeServer { resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> { Class resServiceType = Service.class; try { - if (field.getAnnotation(Resource.class) == null) return; - if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return; //远程模式不得注入 AutoLoad Service - if (!Service.class.isAssignableFrom(field.getType())) return; + if (field.getAnnotation(Resource.class) == null) return null; + if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return null; //远程模式不得注入 AutoLoad Service + if (!Service.class.isAssignableFrom(field.getType())) return null; resServiceType = (Class) field.getType(); - if (resServiceType.getAnnotation(Local.class) == null) return; + if (resServiceType.getAnnotation(Local.class) == null) return null; AutoLoad al = resServiceType.getAnnotation(AutoLoad.class); - if (al == null || al.value()) return; + if (al == null || al.value()) return null; //ResourceFactory resfactory = (isSNCP() ? appResFactory : resourceFactory); SncpClient client = srcObj instanceof Service ? Sncp.getSncpClient((Service) srcObj) : null; @@ -258,31 +260,35 @@ public abstract class NodeServer { rf.inject(resourceName, service, self); // 给其可能包含@Resource的字段赋值; if (!application.isCompileMode()) service.init(null); logger.info("[" + Thread.currentThread().getName() + "] Load Service(@Local @AutoLoad service = " + resServiceType.getSimpleName() + ", resourceName = '" + resourceName + "')"); + return service; } catch (Exception e) { logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] Load @Local @AutoLoad(false) Service inject " + resServiceType + " to " + srcObj + " error", e); + return null; } }, Service.class); //------------------------------------- 注册 DataSource -------------------------------------------------------- resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> { try { - if (field.getAnnotation(Resource.class) == null) return; - if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return; //远程模式不得注入 DataSource + if (field.getAnnotation(Resource.class) == null) return null; + if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return null; //远程模式不得注入 DataSource DataSource source = application.loadDataSource(resourceName, false); field.set(srcObj, source); + return source; } catch (Exception e) { logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] DataSource inject to " + srcObj + " error", e); + return null; } }, DataSource.class); //------------------------------------- 注册 CacheSource -------------------------------------------------------- resourceFactory.register(new ResourceTypeLoader() { @Override - public void load(ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, final Object attachment) { + public Object load(ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, final Object attachment) { try { - if (field.getAnnotation(Resource.class) == null) return; + if (field.getAnnotation(Resource.class) == null) return null; if (!(srcObj instanceof Service)) throw new RuntimeException("CacheSource must be inject in Service, cannot " + srcObj); - if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return; //远程模式不需要注入 CacheSource + if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return null; //远程模式不需要注入 CacheSource final Service srcService = (Service) srcObj; SncpClient client = Sncp.getSncpClient(srcService); final InetSocketAddress sncpAddr = client == null ? null : client.getClientAddress(); @@ -298,8 +304,10 @@ public abstract class NodeServer { } } logger.info("[" + Thread.currentThread().getName() + "] Load CacheSource (type = " + (source == null ? null : source.getClass().getSimpleName()) + ", resourceName = '" + resourceName + "')"); + return source; } catch (Exception e) { logger.log(Level.SEVERE, "DataSource inject error", e); + return null; } } @@ -312,10 +320,10 @@ public abstract class NodeServer { //------------------------------------- 注册 WebSocketNode -------------------------------------------------------- resourceFactory.register(new ResourceTypeLoader() { @Override - public void load(ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, final Object attachment) { + public Object load(ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, final Object attachment) { try { - if (field.getAnnotation(Resource.class) == null) return; - if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return; //远程模式不需要注入 WebSocketNode + if (field.getAnnotation(Resource.class) == null) return null; + if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return null; //远程模式不需要注入 WebSocketNode Service nodeService = (Service) rf.find(resourceName, WebSocketNode.class); if (nodeService == null) { final HashSet groups = new HashSet<>(); @@ -336,8 +344,10 @@ public abstract class NodeServer { interceptorServices.add(nodeService); if (consumer != null) consumer.accept(null, nodeService); } + return nodeService; } catch (Exception e) { logger.log(Level.SEVERE, "WebSocketNode inject error", e); + return null; } } @@ -388,7 +398,7 @@ public abstract class NodeServer { 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; + return null; } RedkaleClassLoader.putReflectionPublicMethods(serviceImplClass.getName()); MessageAgent agent = null; @@ -424,6 +434,7 @@ public abstract class NodeServer { if (consumer != null) consumer.accept(agent, service); } serviceCount.incrementAndGet(); + return service; } catch (RuntimeException ex) { throw ex; } catch (Exception e) { diff --git a/src/main/java/org/redkale/mq/HttpMessageClusterClient.java b/src/main/java/org/redkale/mq/HttpMessageClusterClient.java index 7503aedde..08ae61ac3 100644 --- a/src/main/java/org/redkale/mq/HttpMessageClusterClient.java +++ b/src/main/java/org/redkale/mq/HttpMessageClusterClient.java @@ -41,10 +41,10 @@ public class HttpMessageClusterClient extends HttpMessageClient { protected ClusterAgent clusterAgent; - @Resource(name = "cluster.httpClient") + @Resource(name = "cluster.httpClient", required = false) protected java.net.http.HttpClient httpClient; - @Resource(name = "cluster.httpClient") + @Resource(name = "cluster.httpClient", required = false) protected HttpSimpleClient httpSimpleClient; public HttpMessageClusterClient(Application application, String resourceName, ClusterAgent clusterAgent) { diff --git a/src/main/java/org/redkale/net/Server.java b/src/main/java/org/redkale/net/Server.java index 38639170a..2ac74a1c1 100644 --- a/src/main/java/org/redkale/net/Server.java +++ b/src/main/java/org/redkale/net/Server.java @@ -34,7 +34,7 @@ public abstract class Server 为 sncpnode 的集合, key: groupid //集合包含 localSncpAddress //如果不是分布式(没有SNCP),source 将不会被用到 - @Resource(name = "$") + @Resource(name = "$", required = false) protected CacheSource source; //当前节点的本地WebSocketEngine diff --git a/src/main/java/org/redkale/net/http/WebSocketServlet.java b/src/main/java/org/redkale/net/http/WebSocketServlet.java index 7ab101244..b897cb8e1 100644 --- a/src/main/java/org/redkale/net/http/WebSocketServlet.java +++ b/src/main/java/org/redkale/net/http/WebSocketServlet.java @@ -18,6 +18,7 @@ import java.util.logging.*; import java.util.zip.*; import javax.annotation.*; import org.redkale.boot.Application; +import static org.redkale.boot.Application.RESNAME_SERVER_RESFACTORY; import org.redkale.convert.Convert; import org.redkale.mq.MessageAgent; import org.redkale.net.*; @@ -103,22 +104,22 @@ public abstract class WebSocketServlet extends HttpServlet implements Resourcabl protected MessageAgent messageAgent; - @Resource(name = "jsonconvert") + @Resource(name = "jsonconvert", required = false) protected Convert jsonConvert; - @Resource(name = "$_textconvert") + @Resource(name = "$_textconvert", required = false) protected Convert textConvert; - @Resource(name = "$_binaryconvert") + @Resource(name = "$_binaryconvert", required = false) protected Convert binaryConvert; - @Resource(name = "$_sendconvert") + @Resource(name = "$_sendconvert", required = false) protected Convert sendConvert; @Resource(name = "$") protected WebSocketNode node; - @Resource(name = "SERVER_RESFACTORY") + @Resource(name = RESNAME_SERVER_RESFACTORY) protected ResourceFactory resourceFactory; protected WebSocketServlet() { diff --git a/src/main/java/org/redkale/source/CacheMemorySource.java b/src/main/java/org/redkale/source/CacheMemorySource.java index 26ce7e765..02e920c44 100644 --- a/src/main/java/org/redkale/source/CacheMemorySource.java +++ b/src/main/java/org/redkale/source/CacheMemorySource.java @@ -36,7 +36,7 @@ public final class CacheMemorySource extends AbstractCacheSource { @Resource private JsonConvert defaultConvert; - @Resource(name = "$_convert") + @Resource(name = "$_convert", required = false) private JsonConvert convert; private String name; diff --git a/src/main/java/org/redkale/util/ResourceFactory.java b/src/main/java/org/redkale/util/ResourceFactory.java index 1d0c0d60f..616fbdc54 100644 --- a/src/main/java/org/redkale/util/ResourceFactory.java +++ b/src/main/java/org/redkale/util/ResourceFactory.java @@ -434,7 +434,6 @@ public final class ResourceFactory { /** * 将多个以指定资源名的String对象注入到资源池中 - * properties的key一般以"property."开头 * * @param properties 资源键值对 * @param environmentName 额外的资源名 @@ -448,11 +447,7 @@ public final class ResourceFactory { properties.forEach((k, v) -> { Object old = register(true, k.toString(), String.class, v, wrappers); if (!Objects.equals(v, old)) { - String key = k.toString(); - if (key.startsWith("property.")) { - key = key.substring("property.".length()); - } - environmentEventList.add(ResourceEvent.create(key, v, old)); + environmentEventList.add(ResourceEvent.create(k.toString(), v, old)); } }); Map envListenMap = new LinkedHashMap<>(); @@ -695,12 +690,12 @@ public final class ResourceFactory { for (Field field : clazz.getDeclaredFields()) { if (Modifier.isStatic(field.getModifiers())) continue; field.setAccessible(true); - final Class classtype = field.getType(); + final Class classType = field.getType(); Resource rc = field.getAnnotation(Resource.class); if (rc == null) { //深度注入 - if (Convert.class.isAssignableFrom(classtype)) continue; - if (ConvertFactory.class.isAssignableFrom(classtype)) continue; - if (ResourceFactory.class.isAssignableFrom(classtype)) continue; + if (Convert.class.isAssignableFrom(classType)) continue; + if (ConvertFactory.class.isAssignableFrom(classType)) continue; + if (ResourceFactory.class.isAssignableFrom(classType)) continue; boolean flag = true; //是否没有重复 Object ns = field.get(srcObj); for (Object o : list) { @@ -726,7 +721,7 @@ public final class ResourceFactory { } if (Modifier.isFinal(field.getModifiers())) continue; RedkaleClassLoader.putReflectionField(cname, field); - final Type genctype = TypeToken.containsUnknownType(field.getGenericType()) + final Type gencType = TypeToken.containsUnknownType(field.getGenericType()) ? TypeToken.getGenericType(field.getGenericType(), srcObj.getClass()) : field.getGenericType(); if (consumer != null) consumer.accept(srcObj, field); String tname = rc.name(); @@ -746,75 +741,95 @@ public final class ResourceFactory { } boolean autoRegNull = true; final String rcname = formatResourceName(srcResourceName, tname); - Object rs; + Object rs = null; if (rcname.startsWith("system.property.")) { rs = System.getProperty(rcname.substring("system.property.".length())); } else { - ResourceEntry re = findEntry(rcname, genctype); + ResourceEntry re = findEntry(rcname, gencType); if (re == null) { - if (rcname.startsWith("property.")) { + if (classType.isPrimitive() || classType == Integer.class + || classType == Long.class || classType == Short.class + || classType == Boolean.class || classType == Byte.class + || classType == Float.class || classType == Double.class || classType == BigInteger.class) { re = findEntry(rcname, String.class); + if (re == null && rcname.startsWith("property.")) { //兼容2.8.0之前版本自动追加property.开头的配置项 + re = findEntry(rcname.substring("property.".length()), String.class); + } + } else if (classType == String.class && rcname.startsWith("property.")) {//兼容2.8.0之前版本自动追加property.开头的配置项 + re = findEntry(rcname.substring("property.".length()), String.class); } else { - re = findEntry(rcname, classtype); + re = findEntry(rcname, classType); } } if (re == null) { - ResourceTypeLoader it = findTypeLoader(genctype, field); + ResourceTypeLoader it = findTypeLoader(gencType, field); if (it != null) { - it.load(this, srcResourceName, srcObj, rcname, field, attachment); + rs = it.load(this, srcResourceName, srcObj, rcname, field, attachment); autoRegNull = it.autoNone(); - re = findEntry(rcname, genctype); + if (rs == null) { + re = findEntry(rcname, gencType); + } } } - if (re == null && genctype != classtype) { - re = findEntry(rcname, classtype); + if (rs == null && re == null && gencType != classType) { + re = findEntry(rcname, classType); if (re == null) { - if (rcname.startsWith("property.")) { + if (classType.isPrimitive() || classType == Integer.class + || classType == Long.class || classType == Short.class + || classType == Boolean.class || classType == Byte.class + || classType == Float.class || classType == Double.class + || classType == BigInteger.class) { re = findEntry(rcname, String.class); } else { - re = findEntry(rcname, classtype); + re = findEntry(rcname, classType); } } if (re == null) { - ResourceTypeLoader it = findTypeLoader(classtype, field); + ResourceTypeLoader it = findTypeLoader(classType, field); if (it != null) { - it.load(this, srcResourceName, srcObj, rcname, field, attachment); + rs = it.load(this, srcResourceName, srcObj, rcname, field, attachment); autoRegNull = it.autoNone(); - re = findEntry(rcname, classtype); + if (rs == null) { + re = findEntry(rcname, classType); + } } } } - if (re == null && autoRegNull) { - register(rcname, genctype, null); //自动注入null的值 - re = findEntry(rcname, genctype); + if (rs == null && re == null && autoRegNull) { + register(rcname, gencType, null); //自动注入null的值 + re = findEntry(rcname, gencType); } if (re != null) { re.elements.add(new ResourceElement<>(srcObj, field)); rs = re.value; - } else { - rs = null; } } - if (rs != null && !rs.getClass().isPrimitive() && classtype.isPrimitive()) { - if (classtype == int.class) { + if (rs != null && !rs.getClass().isPrimitive() && (classType.isPrimitive() + || classType == Integer.class || classType == Long.class + || classType == Short.class || classType == Boolean.class + || classType == Byte.class || classType == Float.class + || classType == Double.class || classType == BigInteger.class)) { + if (classType == int.class || classType == Integer.class) { rs = Integer.decode(rs.toString()); - } else if (classtype == long.class) { + } else if (classType == long.class || classType == Long.class) { rs = Long.decode(rs.toString()); - } else if (classtype == short.class) { + } else if (classType == short.class || classType == Short.class) { rs = Short.decode(rs.toString()); - } else if (classtype == boolean.class) { + } else if (classType == boolean.class || classType == Boolean.class) { rs = "true".equalsIgnoreCase(rs.toString()); - } else if (classtype == byte.class) { + } else if (classType == byte.class || classType == Byte.class) { rs = Byte.decode(rs.toString()); - } else if (classtype == float.class) { + } else if (classType == float.class || classType == Float.class) { rs = Float.parseFloat(rs.toString()); - } else if (classtype == double.class) { + } else if (classType == double.class || classType == Double.class) { rs = Double.parseDouble(rs.toString()); + } else if (classType == BigInteger.class) { + rs = new BigInteger(rs.toString()); } } if (rs != null) field.set(srcObj, rs); if (rs == null && rc.required()) { - throw new ResourceInjectException("resource(type=" + field.getType().getSimpleName() + ", field=" + field.getName() + ", name=" + rcname + ") must exists in " + srcObj.getClass().getName()); + throw new ResourceInjectException("resource(type=" + field.getType().getSimpleName() + ".class, field=" + field.getName() + ", name='" + rcname + "') must exists in " + srcObj.getClass().getName()); } } } while ((clazz = clazz.getSuperclass()) != Object.class); diff --git a/src/main/java/org/redkale/util/ResourceTypeLoader.java b/src/main/java/org/redkale/util/ResourceTypeLoader.java index be1133c1e..97ccd3554 100644 --- a/src/main/java/org/redkale/util/ResourceTypeLoader.java +++ b/src/main/java/org/redkale/util/ResourceTypeLoader.java @@ -14,7 +14,7 @@ import java.lang.reflect.Field; */ public interface ResourceTypeLoader { - public void load(ResourceFactory factory, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment); + public Object load(ResourceFactory factory, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment); // 返回true 表示调用ResourceLoader之后资源仍不存在,则会在ResourceFactory里注入默认值null,返回false表示资源不存在下次仍会调用ResourceLoader自行处理 default boolean autoNone() { diff --git a/src/test/java/org/redkale/test/util/ResourceListenerTest.java b/src/test/java/org/redkale/test/util/ResourceListenerTest.java index e3df657d5..e8aa8af52 100644 --- a/src/test/java/org/redkale/test/util/ResourceListenerTest.java +++ b/src/test/java/org/redkale/test/util/ResourceListenerTest.java @@ -62,10 +62,10 @@ public class ResourceListenerTest { public final AtomicInteger counter = new AtomicInteger(); - @Resource(name = "property.id") + @Resource(name = "property.id", required = false) private String id; - @Resource(name = "property.desc") + @Resource(name = "property.desc", required = false) private String desc; @ResourceListener @@ -107,7 +107,7 @@ public class ResourceListenerTest { public final AtomicInteger counter = new AtomicInteger(); - @Resource(name = "property.id") + @Resource(name = "property.id", required = false) private String id; @Resource diff --git a/src/test/java/org/redkale/test/util/ResourceTest.java b/src/test/java/org/redkale/test/util/ResourceTest.java index 4799a38cc..1f86d0b44 100644 --- a/src/test/java/org/redkale/test/util/ResourceTest.java +++ b/src/test/java/org/redkale/test/util/ResourceTest.java @@ -53,7 +53,7 @@ public class ResourceTest { props.put("property.id", "5555"); props.put("property.desc", "my desc"); factory.register(props); - + bservice = new BService("ffff"); factory.register(bservice); //更新Resource池内name=""的BService资源, 同时ResourceFactory会自动更新aservice的bservice对象 factory.inject(bservice); @@ -68,7 +68,7 @@ class BService { @Resource(name = "property.id") private String id; - @Resource(name = "property.desc") + @Resource(name = "property.desc", required = false) private String desc; @Resource @@ -126,10 +126,10 @@ class AService { @Resource(name = "property.id") //property.开头的资源名允许String自动转换成primitive数值类型 private int intid; - @Resource(name = "bigint") + @Resource(name = "bigint", required = false) private BigInteger bigint; - @Resource(name = "seqid") + @Resource(name = "seqid", required = false) private int seqid; @Resource