废弃依赖注入配置项时自动加入"property."前缀

This commit is contained in:
Redkale
2022-12-11 21:37:23 +08:00
parent b6a0885927
commit 4a91e6eb18
12 changed files with 135 additions and 111 deletions

View File

@@ -124,7 +124,7 @@ public final class Application {
/** /**
* 当前Server的ResourceFactory * 当前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; private static final int UDP_CAPACITY = 1024;
@@ -682,10 +682,10 @@ public final class Application {
in.close(); in.close();
if (logger.isLoggable(Level.FINEST)) logger.log(Level.FINEST, "load properties(" + dfload + ") size = " + ps.size()); 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.开头配置项 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); agentEnvs.put(x, y);
} else { } 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) { } catch (Exception e) {
@@ -737,17 +737,11 @@ public final class Application {
String key = prop.getValue("name"); String key = prop.getValue("name");
String value = prop.getValue("value"); String value = prop.getValue("value");
if (key == null || value == null) continue; 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); oldEnvs.put(key, value);
} }
agentEnvs.forEach((k, v) -> { agentEnvs.forEach((k, v) -> {
if (k.toString().startsWith("redkale.")) { if (k.toString().startsWith("redkale.")) {
dyncProps.put(k, v); 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 { } else {
oldEnvs.put(k, v); //新配置项会覆盖旧的 oldEnvs.put(k, v); //新配置项会覆盖旧的
} }
@@ -830,12 +824,9 @@ public final class Application {
} }
} else if (key.startsWith("mimetype.property.")) { } else if (key.startsWith("mimetype.property.")) {
MimeType.add(key.substring("mimetype.property.".length()), value); MimeType.add(key.substring("mimetype.property.".length()), value);
} else if (key.startsWith("property.")) {
this.envProperties.put(key, value);
resourceFactory.register(key, value);
} else { } else {
this.envProperties.put(key, value); 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() { this.resourceFactory.register(new ResourceTypeLoader() {
@Override @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 { try {
Resource res = field.getAnnotation(Resource.class); Resource res = field.getAnnotation(Resource.class);
if (res == null) return; if (res == null) return null;
if (srcObj instanceof Service && Sncp.isRemote((Service) srcObj)) return; //远程模式不得注入 if (srcObj instanceof Service && Sncp.isRemote((Service) srcObj)) return null; //远程模式不得注入
Class type = field.getType(); Class type = field.getType();
if (type == Application.class) { if (type == Application.class) {
field.set(srcObj, application); field.set(srcObj, application);
return application;
} else if (type == ResourceFactory.class) { } else if (type == ResourceFactory.class) {
boolean serv = RESNAME_SERVER_RESFACTORY.equals(res.name()) || res.name().equalsIgnoreCase("server"); 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) { } else if (type == TransportFactory.class) {
field.set(srcObj, application.sncpTransportFactory); field.set(srcObj, application.sncpTransportFactory);
return application.sncpTransportFactory;
} else if (type == NodeSncpServer.class) { } else if (type == NodeSncpServer.class) {
NodeServer server = null; NodeServer server = null;
for (NodeServer ns : application.getNodeServers()) { for (NodeServer ns : application.getNodeServers()) {
@@ -1010,6 +1005,7 @@ public final class Application {
} }
} }
field.set(srcObj, server); field.set(srcObj, server);
return server;
} else if (type == NodeHttpServer.class) { } else if (type == NodeHttpServer.class) {
NodeServer server = null; NodeServer server = null;
for (NodeServer ns : application.getNodeServers()) { for (NodeServer ns : application.getNodeServers()) {
@@ -1020,6 +1016,7 @@ public final class Application {
} }
} }
field.set(srcObj, server); field.set(srcObj, server);
return server;
} else if (type == NodeWatchServer.class) { } else if (type == NodeWatchServer.class) {
NodeServer server = null; NodeServer server = null;
for (NodeServer ns : application.getNodeServers()) { for (NodeServer ns : application.getNodeServers()) {
@@ -1030,12 +1027,15 @@ public final class Application {
} }
} }
field.set(srcObj, server); field.set(srcObj, server);
return server;
} }
// if (type == WatchFactory.class) { // if (type == WatchFactory.class) {
// field.set(src, application.watchFactory); // field.set(src, application.watchFactory);
// } // }
return null;
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "Resource inject error", e); logger.log(Level.SEVERE, "Resource inject error", e);
return null;
} }
} }
@@ -1049,7 +1049,7 @@ public final class Application {
//------------------------------------ 注册 java.net.http.HttpClient ------------------------------------ //------------------------------------ 注册 java.net.http.HttpClient ------------------------------------
resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> { resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> {
try { 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(); java.net.http.HttpClient.Builder builder = java.net.http.HttpClient.newBuilder();
if (resourceName.endsWith(".1.1")) { if (resourceName.endsWith(".1.1")) {
builder.version(HttpClient.Version.HTTP_1_1); builder.version(HttpClient.Version.HTTP_1_1);
@@ -1060,20 +1060,24 @@ public final class Application {
field.set(srcObj, httpClient); field.set(srcObj, httpClient);
rf.inject(resourceName, httpClient, null); // 给其可能包含@Resource的字段赋值; rf.inject(resourceName, httpClient, null); // 给其可能包含@Resource的字段赋值;
rf.register(resourceName, java.net.http.HttpClient.class, httpClient); rf.register(resourceName, java.net.http.HttpClient.class, httpClient);
return httpClient;
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] java.net.http.HttpClient inject error", e); logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] java.net.http.HttpClient inject error", e);
return null;
} }
}, java.net.http.HttpClient.class); }, java.net.http.HttpClient.class);
//------------------------------------ 注册 HttpSimpleClient ------------------------------------ //------------------------------------ 注册 HttpSimpleClient ------------------------------------
resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> { resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> {
try { try {
if (field.getAnnotation(Resource.class) == null) return; if (field.getAnnotation(Resource.class) == null) return null;
HttpSimpleClient httpClient = HttpSimpleClient.create(clientAsyncGroup); HttpSimpleClient httpClient = HttpSimpleClient.create(clientAsyncGroup);
field.set(srcObj, httpClient); field.set(srcObj, httpClient);
rf.inject(resourceName, httpClient, null); // 给其可能包含@Resource的字段赋值; rf.inject(resourceName, httpClient, null); // 给其可能包含@Resource的字段赋值;
rf.register(resourceName, HttpSimpleClient.class, httpClient); rf.register(resourceName, HttpSimpleClient.class, httpClient);
return httpClient;
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] HttpClient inject error", e); logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] HttpClient inject error", e);
return null;
} }
}, HttpSimpleClient.class); }, HttpSimpleClient.class);
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@@ -1108,20 +1112,22 @@ public final class Application {
//------------------------------------ 注册 HttpMessageClient ------------------------------------ //------------------------------------ 注册 HttpMessageClient ------------------------------------
resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> { resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> {
try { try {
if (field.getAnnotation(Resource.class) == null) return; if (field.getAnnotation(Resource.class) == null) return null;
if (clusterAgent == null) { if (clusterAgent == null) {
HttpMessageClient messageClient = new HttpMessageLocalClient(application, resourceName); HttpMessageClient messageClient = new HttpMessageLocalClient(application, resourceName);
field.set(srcObj, messageClient); field.set(srcObj, messageClient);
rf.inject(resourceName, messageClient, null); // 给其可能包含@Resource的字段赋值; rf.inject(resourceName, messageClient, null); // 给其可能包含@Resource的字段赋值;
rf.register(resourceName, HttpMessageClient.class, messageClient); rf.register(resourceName, HttpMessageClient.class, messageClient);
return; return messageClient;
} }
HttpMessageClient messageClient = new HttpMessageClusterClient(application, resourceName, clusterAgent); HttpMessageClient messageClient = new HttpMessageClusterClient(application, resourceName, clusterAgent);
field.set(srcObj, messageClient); field.set(srcObj, messageClient);
rf.inject(resourceName, messageClient, null); // 给其可能包含@Resource的字段赋值; rf.inject(resourceName, messageClient, null); // 给其可能包含@Resource的字段赋值;
rf.register(resourceName, HttpMessageClient.class, messageClient); rf.register(resourceName, HttpMessageClient.class, messageClient);
return messageClient;
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] HttpMessageClient inject error", e); logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] HttpMessageClient inject error", e);
return null;
} }
}, HttpMessageClient.class); }, HttpMessageClient.class);
initResources(); initResources();
@@ -1943,22 +1949,11 @@ public final class Application {
if (event.newValue() != null) { if (event.newValue() != null) {
MimeType.add(propName, event.newValue()); 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.")) { } else if (event.name().startsWith("redkale.")) {
logger.log(Level.WARNING, "not support the environment property key " + event.name() + " on change event"); logger.log(Level.WARNING, "not support the environment property key " + event.name() + " on change event");
} else { } else {
if (!Objects.equals(event.newValue(), this.envProperties.getProperty(event.name()))) { 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 (event.newValue() == null) {
if (this.envProperties.containsKey(event.name())) { if (this.envProperties.containsKey(event.name())) {
envRemovedKeys.add(event.name()); envRemovedKeys.add(event.name());

View File

@@ -104,8 +104,8 @@ public class NodeHttpServer extends NodeServer {
final ResourceFactory regFactory = application.getResourceFactory(); final ResourceFactory regFactory = application.getResourceFactory();
resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, Object attachment) -> { //主要用于单点的服务 resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, Object attachment) -> { //主要用于单点的服务
try { try {
if (field.getAnnotation(Resource.class) == null) return; if (field.getAnnotation(Resource.class) == null) return null;
if (!(srcObj instanceof WebSocketServlet)) return; if (!(srcObj instanceof WebSocketServlet)) return null;
ResourceTypeLoader loader = null; ResourceTypeLoader loader = null;
ResourceFactory sncpResFactory = null; ResourceFactory sncpResFactory = null;
for (NodeServer ns : application.servers) { for (NodeServer ns : application.servers) {
@@ -137,9 +137,11 @@ public class NodeHttpServer extends NodeServer {
resourceFactory.inject(resourceName, nodeService, self); resourceFactory.inject(resourceName, nodeService, self);
field.set(srcObj, nodeService); field.set(srcObj, nodeService);
logger.fine("[" + Thread.currentThread().getName() + "] Load Service " + nodeService); logger.fine("[" + Thread.currentThread().getName() + "] Load Service " + nodeService);
return nodeService;
} }
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "WebSocketNode inject error", e); logger.log(Level.SEVERE, "WebSocketNode inject error", e);
return null;
} }
}, WebSocketNode.class); }, WebSocketNode.class);
} }

View File

@@ -216,10 +216,10 @@ public abstract class NodeServer {
resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> { resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> {
try { try {
Resource res = field.getAnnotation(Resource.class); Resource res = field.getAnnotation(Resource.class);
if (res == null || !res.name().startsWith("properties.")) return; if (res == null || !res.name().startsWith("properties.")) return null;
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return; //远程模式不得注入 DataSource if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return null; //远程模式不得注入 DataSource
Class type = field.getType(); Class type = field.getType();
if (type != AnyValue.class && type != AnyValue[].class) return; if (type != AnyValue.class && type != AnyValue[].class) return null;
Object resource = null; Object resource = null;
final AnyValue properties = application.getAppConfig().getAnyValue("properties"); final AnyValue properties = application.getAppConfig().getAnyValue("properties");
if (properties != null && type == AnyValue.class) { if (properties != null && type == AnyValue.class) {
@@ -230,8 +230,10 @@ public abstract class NodeServer {
appResFactory.register(resourceName, AnyValue[].class, resource); appResFactory.register(resourceName, AnyValue[].class, resource);
} }
field.set(srcObj, resource); field.set(srcObj, resource);
return resource;
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "Resource inject error", e); logger.log(Level.SEVERE, "Resource inject error", e);
return null;
} }
}, AnyValue.class, AnyValue[].class); }, 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) -> { resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> {
Class<Service> resServiceType = Service.class; Class<Service> resServiceType = Service.class;
try { try {
if (field.getAnnotation(Resource.class) == null) return; if (field.getAnnotation(Resource.class) == null) return null;
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return; //远程模式不得注入 AutoLoad Service if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return null; //远程模式不得注入 AutoLoad Service
if (!Service.class.isAssignableFrom(field.getType())) return; if (!Service.class.isAssignableFrom(field.getType())) return null;
resServiceType = (Class) field.getType(); 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); AutoLoad al = resServiceType.getAnnotation(AutoLoad.class);
if (al == null || al.value()) return; if (al == null || al.value()) return null;
//ResourceFactory resfactory = (isSNCP() ? appResFactory : resourceFactory); //ResourceFactory resfactory = (isSNCP() ? appResFactory : resourceFactory);
SncpClient client = srcObj instanceof Service ? Sncp.getSncpClient((Service) srcObj) : null; SncpClient client = srcObj instanceof Service ? Sncp.getSncpClient((Service) srcObj) : null;
@@ -258,31 +260,35 @@ public abstract class NodeServer {
rf.inject(resourceName, service, self); // 给其可能包含@Resource的字段赋值; rf.inject(resourceName, service, self); // 给其可能包含@Resource的字段赋值;
if (!application.isCompileMode()) service.init(null); if (!application.isCompileMode()) service.init(null);
logger.info("[" + Thread.currentThread().getName() + "] Load Service(@Local @AutoLoad service = " + resServiceType.getSimpleName() + ", resourceName = '" + resourceName + "')"); logger.info("[" + Thread.currentThread().getName() + "] Load Service(@Local @AutoLoad service = " + resServiceType.getSimpleName() + ", resourceName = '" + resourceName + "')");
return service;
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] Load @Local @AutoLoad(false) Service inject " + resServiceType + " to " + srcObj + " error", e); logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] Load @Local @AutoLoad(false) Service inject " + resServiceType + " to " + srcObj + " error", e);
return null;
} }
}, Service.class); }, Service.class);
//------------------------------------- 注册 DataSource -------------------------------------------------------- //------------------------------------- 注册 DataSource --------------------------------------------------------
resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> { resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> {
try { try {
if (field.getAnnotation(Resource.class) == null) return; if (field.getAnnotation(Resource.class) == null) return null;
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return; //远程模式不得注入 DataSource if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return null; //远程模式不得注入 DataSource
DataSource source = application.loadDataSource(resourceName, false); DataSource source = application.loadDataSource(resourceName, false);
field.set(srcObj, source); field.set(srcObj, source);
return source;
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] DataSource inject to " + srcObj + " error", e); logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] DataSource inject to " + srcObj + " error", e);
return null;
} }
}, DataSource.class); }, DataSource.class);
//------------------------------------- 注册 CacheSource -------------------------------------------------------- //------------------------------------- 注册 CacheSource --------------------------------------------------------
resourceFactory.register(new ResourceTypeLoader() { resourceFactory.register(new ResourceTypeLoader() {
@Override @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 { 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)) 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; final Service srcService = (Service) srcObj;
SncpClient client = Sncp.getSncpClient(srcService); SncpClient client = Sncp.getSncpClient(srcService);
final InetSocketAddress sncpAddr = client == null ? null : client.getClientAddress(); 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 + "')"); logger.info("[" + Thread.currentThread().getName() + "] Load CacheSource (type = " + (source == null ? null : source.getClass().getSimpleName()) + ", resourceName = '" + resourceName + "')");
return source;
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "DataSource inject error", e); logger.log(Level.SEVERE, "DataSource inject error", e);
return null;
} }
} }
@@ -312,10 +320,10 @@ public abstract class NodeServer {
//------------------------------------- 注册 WebSocketNode -------------------------------------------------------- //------------------------------------- 注册 WebSocketNode --------------------------------------------------------
resourceFactory.register(new ResourceTypeLoader() { resourceFactory.register(new ResourceTypeLoader() {
@Override @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 { try {
if (field.getAnnotation(Resource.class) == null) return; if (field.getAnnotation(Resource.class) == null) return null;
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return; //远程模式不需要注入 WebSocketNode if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return null; //远程模式不需要注入 WebSocketNode
Service nodeService = (Service) rf.find(resourceName, WebSocketNode.class); Service nodeService = (Service) rf.find(resourceName, WebSocketNode.class);
if (nodeService == null) { if (nodeService == null) {
final HashSet<String> groups = new HashSet<>(); final HashSet<String> groups = new HashSet<>();
@@ -336,8 +344,10 @@ public abstract class NodeServer {
interceptorServices.add(nodeService); interceptorServices.add(nodeService);
if (consumer != null) consumer.accept(null, nodeService); if (consumer != null) consumer.accept(null, nodeService);
} }
return nodeService;
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "WebSocketNode inject error", 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")) { 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"); logger.log(Level.FINE, serviceImplClass + " cannot load because not found less one public non-final method");
} }
return; return null;
} }
RedkaleClassLoader.putReflectionPublicMethods(serviceImplClass.getName()); RedkaleClassLoader.putReflectionPublicMethods(serviceImplClass.getName());
MessageAgent agent = null; MessageAgent agent = null;
@@ -424,6 +434,7 @@ public abstract class NodeServer {
if (consumer != null) consumer.accept(agent, service); if (consumer != null) consumer.accept(agent, service);
} }
serviceCount.incrementAndGet(); serviceCount.incrementAndGet();
return service;
} catch (RuntimeException ex) { } catch (RuntimeException ex) {
throw ex; throw ex;
} catch (Exception e) { } catch (Exception e) {

View File

@@ -41,10 +41,10 @@ public class HttpMessageClusterClient extends HttpMessageClient {
protected ClusterAgent clusterAgent; protected ClusterAgent clusterAgent;
@Resource(name = "cluster.httpClient") @Resource(name = "cluster.httpClient", required = false)
protected java.net.http.HttpClient httpClient; protected java.net.http.HttpClient httpClient;
@Resource(name = "cluster.httpClient") @Resource(name = "cluster.httpClient", required = false)
protected HttpSimpleClient httpSimpleClient; protected HttpSimpleClient httpSimpleClient;
public HttpMessageClusterClient(Application application, String resourceName, ClusterAgent clusterAgent) { public HttpMessageClusterClient(Application application, String resourceName, ClusterAgent clusterAgent) {

View File

@@ -34,7 +34,7 @@ public abstract class Server<K extends Serializable, C extends Context, R extend
//@Deprecated //@deprecated 2.3.0 使用RESNAME_APP_EXECUTOR //@Deprecated //@deprecated 2.3.0 使用RESNAME_APP_EXECUTOR
//public static final String RESNAME_SERVER_EXECUTOR2 = "SERVER_EXECUTOR"; //public static final String RESNAME_SERVER_EXECUTOR2 = "SERVER_EXECUTOR";
public static final String RESNAME_SERVER_RESFACTORY = "SERVER_RESFACTORY"; //public static final String RESNAME_SERVER_RESFACTORY = "SERVER_RESFACTORY";
protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName()); protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName());

View File

@@ -40,7 +40,7 @@ public abstract class WebSocketNode {
protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName()); protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName());
//"SNCP_ADDR" 如果不是分布式(没有SNCP) 值为null //"SNCP_ADDR" 如果不是分布式(没有SNCP) 值为null
@Resource(name = Application.RESNAME_SNCP_ADDR) @Resource(name = Application.RESNAME_SNCP_ADDR, required = false)
protected InetSocketAddress localSncpAddress; //为SncpServer的服务address protected InetSocketAddress localSncpAddress; //为SncpServer的服务address
protected WebSocketAddress wsNodeAddress; protected WebSocketAddress wsNodeAddress;
@@ -51,13 +51,13 @@ public abstract class WebSocketNode {
@RpcRemote @RpcRemote
protected WebSocketNode remoteNode; protected WebSocketNode remoteNode;
@Resource(name = "$_sendconvert") @Resource(name = "$_sendconvert", required = false)
protected Convert sendConvert; protected Convert sendConvert;
//存放所有用户分布在节点上的队列信息,Set<WebSocketAddress> 为 sncpnode 的集合, key: groupid //存放所有用户分布在节点上的队列信息,Set<WebSocketAddress> 为 sncpnode 的集合, key: groupid
//集合包含 localSncpAddress //集合包含 localSncpAddress
//如果不是分布式(没有SNCP)source 将不会被用到 //如果不是分布式(没有SNCP)source 将不会被用到
@Resource(name = "$") @Resource(name = "$", required = false)
protected CacheSource source; protected CacheSource source;
//当前节点的本地WebSocketEngine //当前节点的本地WebSocketEngine

View File

@@ -18,6 +18,7 @@ import java.util.logging.*;
import java.util.zip.*; import java.util.zip.*;
import javax.annotation.*; import javax.annotation.*;
import org.redkale.boot.Application; import org.redkale.boot.Application;
import static org.redkale.boot.Application.RESNAME_SERVER_RESFACTORY;
import org.redkale.convert.Convert; import org.redkale.convert.Convert;
import org.redkale.mq.MessageAgent; import org.redkale.mq.MessageAgent;
import org.redkale.net.*; import org.redkale.net.*;
@@ -103,22 +104,22 @@ public abstract class WebSocketServlet extends HttpServlet implements Resourcabl
protected MessageAgent messageAgent; protected MessageAgent messageAgent;
@Resource(name = "jsonconvert") @Resource(name = "jsonconvert", required = false)
protected Convert jsonConvert; protected Convert jsonConvert;
@Resource(name = "$_textconvert") @Resource(name = "$_textconvert", required = false)
protected Convert textConvert; protected Convert textConvert;
@Resource(name = "$_binaryconvert") @Resource(name = "$_binaryconvert", required = false)
protected Convert binaryConvert; protected Convert binaryConvert;
@Resource(name = "$_sendconvert") @Resource(name = "$_sendconvert", required = false)
protected Convert sendConvert; protected Convert sendConvert;
@Resource(name = "$") @Resource(name = "$")
protected WebSocketNode node; protected WebSocketNode node;
@Resource(name = "SERVER_RESFACTORY") @Resource(name = RESNAME_SERVER_RESFACTORY)
protected ResourceFactory resourceFactory; protected ResourceFactory resourceFactory;
protected WebSocketServlet() { protected WebSocketServlet() {

View File

@@ -36,7 +36,7 @@ public final class CacheMemorySource extends AbstractCacheSource {
@Resource @Resource
private JsonConvert defaultConvert; private JsonConvert defaultConvert;
@Resource(name = "$_convert") @Resource(name = "$_convert", required = false)
private JsonConvert convert; private JsonConvert convert;
private String name; private String name;

View File

@@ -434,7 +434,6 @@ public final class ResourceFactory {
/** /**
* 将多个以指定资源名的String对象注入到资源池中 * 将多个以指定资源名的String对象注入到资源池中
* properties的key一般以"property."开头
* *
* @param properties 资源键值对 * @param properties 资源键值对
* @param environmentName 额外的资源名 * @param environmentName 额外的资源名
@@ -448,11 +447,7 @@ public final class ResourceFactory {
properties.forEach((k, v) -> { properties.forEach((k, v) -> {
Object old = register(true, k.toString(), String.class, v, wrappers); Object old = register(true, k.toString(), String.class, v, wrappers);
if (!Objects.equals(v, old)) { if (!Objects.equals(v, old)) {
String key = k.toString(); environmentEventList.add(ResourceEvent.create(k.toString(), v, old));
if (key.startsWith("property.")) {
key = key.substring("property.".length());
}
environmentEventList.add(ResourceEvent.create(key, v, old));
} }
}); });
Map<Object, Method> envListenMap = new LinkedHashMap<>(); Map<Object, Method> envListenMap = new LinkedHashMap<>();
@@ -695,12 +690,12 @@ public final class ResourceFactory {
for (Field field : clazz.getDeclaredFields()) { for (Field field : clazz.getDeclaredFields()) {
if (Modifier.isStatic(field.getModifiers())) continue; if (Modifier.isStatic(field.getModifiers())) continue;
field.setAccessible(true); field.setAccessible(true);
final Class classtype = field.getType(); final Class classType = field.getType();
Resource rc = field.getAnnotation(Resource.class); Resource rc = field.getAnnotation(Resource.class);
if (rc == null) { //深度注入 if (rc == null) { //深度注入
if (Convert.class.isAssignableFrom(classtype)) continue; if (Convert.class.isAssignableFrom(classType)) continue;
if (ConvertFactory.class.isAssignableFrom(classtype)) continue; if (ConvertFactory.class.isAssignableFrom(classType)) continue;
if (ResourceFactory.class.isAssignableFrom(classtype)) continue; if (ResourceFactory.class.isAssignableFrom(classType)) continue;
boolean flag = true; //是否没有重复 boolean flag = true; //是否没有重复
Object ns = field.get(srcObj); Object ns = field.get(srcObj);
for (Object o : list) { for (Object o : list) {
@@ -726,7 +721,7 @@ public final class ResourceFactory {
} }
if (Modifier.isFinal(field.getModifiers())) continue; if (Modifier.isFinal(field.getModifiers())) continue;
RedkaleClassLoader.putReflectionField(cname, field); 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(); ? TypeToken.getGenericType(field.getGenericType(), srcObj.getClass()) : field.getGenericType();
if (consumer != null) consumer.accept(srcObj, field); if (consumer != null) consumer.accept(srcObj, field);
String tname = rc.name(); String tname = rc.name();
@@ -746,75 +741,95 @@ public final class ResourceFactory {
} }
boolean autoRegNull = true; boolean autoRegNull = true;
final String rcname = formatResourceName(srcResourceName, tname); final String rcname = formatResourceName(srcResourceName, tname);
Object rs; Object rs = null;
if (rcname.startsWith("system.property.")) { if (rcname.startsWith("system.property.")) {
rs = System.getProperty(rcname.substring("system.property.".length())); rs = System.getProperty(rcname.substring("system.property.".length()));
} else { } else {
ResourceEntry re = findEntry(rcname, genctype); ResourceEntry re = findEntry(rcname, gencType);
if (re == null) { 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); 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 { } else {
re = findEntry(rcname, classtype); re = findEntry(rcname, classType);
} }
} }
if (re == null) { if (re == null) {
ResourceTypeLoader it = findTypeLoader(genctype, field); ResourceTypeLoader it = findTypeLoader(gencType, field);
if (it != null) { if (it != null) {
it.load(this, srcResourceName, srcObj, rcname, field, attachment); rs = it.load(this, srcResourceName, srcObj, rcname, field, attachment);
autoRegNull = it.autoNone(); autoRegNull = it.autoNone();
re = findEntry(rcname, genctype); if (rs == null) {
re = findEntry(rcname, gencType);
}
} }
} }
if (re == null && genctype != classtype) { if (rs == null && re == null && gencType != classType) {
re = findEntry(rcname, classtype); re = findEntry(rcname, classType);
if (re == null) { 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); re = findEntry(rcname, String.class);
} else { } else {
re = findEntry(rcname, classtype); re = findEntry(rcname, classType);
} }
} }
if (re == null) { if (re == null) {
ResourceTypeLoader it = findTypeLoader(classtype, field); ResourceTypeLoader it = findTypeLoader(classType, field);
if (it != null) { if (it != null) {
it.load(this, srcResourceName, srcObj, rcname, field, attachment); rs = it.load(this, srcResourceName, srcObj, rcname, field, attachment);
autoRegNull = it.autoNone(); autoRegNull = it.autoNone();
re = findEntry(rcname, classtype); if (rs == null) {
re = findEntry(rcname, classType);
}
} }
} }
} }
if (re == null && autoRegNull) { if (rs == null && re == null && autoRegNull) {
register(rcname, genctype, null); //自动注入null的值 register(rcname, gencType, null); //自动注入null的值
re = findEntry(rcname, genctype); re = findEntry(rcname, gencType);
} }
if (re != null) { if (re != null) {
re.elements.add(new ResourceElement<>(srcObj, field)); re.elements.add(new ResourceElement<>(srcObj, field));
rs = re.value; rs = re.value;
} else {
rs = null;
} }
} }
if (rs != null && !rs.getClass().isPrimitive() && classtype.isPrimitive()) { if (rs != null && !rs.getClass().isPrimitive() && (classType.isPrimitive()
if (classtype == int.class) { || 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()); rs = Integer.decode(rs.toString());
} else if (classtype == long.class) { } else if (classType == long.class || classType == Long.class) {
rs = Long.decode(rs.toString()); rs = Long.decode(rs.toString());
} else if (classtype == short.class) { } else if (classType == short.class || classType == Short.class) {
rs = Short.decode(rs.toString()); rs = Short.decode(rs.toString());
} else if (classtype == boolean.class) { } else if (classType == boolean.class || classType == Boolean.class) {
rs = "true".equalsIgnoreCase(rs.toString()); rs = "true".equalsIgnoreCase(rs.toString());
} else if (classtype == byte.class) { } else if (classType == byte.class || classType == Byte.class) {
rs = Byte.decode(rs.toString()); rs = Byte.decode(rs.toString());
} else if (classtype == float.class) { } else if (classType == float.class || classType == Float.class) {
rs = Float.parseFloat(rs.toString()); rs = Float.parseFloat(rs.toString());
} else if (classtype == double.class) { } else if (classType == double.class || classType == Double.class) {
rs = Double.parseDouble(rs.toString()); 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) field.set(srcObj, rs);
if (rs == null && rc.required()) { 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); } while ((clazz = clazz.getSuperclass()) != Object.class);

View File

@@ -14,7 +14,7 @@ import java.lang.reflect.Field;
*/ */
public interface ResourceTypeLoader { 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自行处理 // 返回true 表示调用ResourceLoader之后资源仍不存在则会在ResourceFactory里注入默认值null返回false表示资源不存在下次仍会调用ResourceLoader自行处理
default boolean autoNone() { default boolean autoNone() {

View File

@@ -62,10 +62,10 @@ public class ResourceListenerTest {
public final AtomicInteger counter = new AtomicInteger(); public final AtomicInteger counter = new AtomicInteger();
@Resource(name = "property.id") @Resource(name = "property.id", required = false)
private String id; private String id;
@Resource(name = "property.desc") @Resource(name = "property.desc", required = false)
private String desc; private String desc;
@ResourceListener @ResourceListener
@@ -107,7 +107,7 @@ public class ResourceListenerTest {
public final AtomicInteger counter = new AtomicInteger(); public final AtomicInteger counter = new AtomicInteger();
@Resource(name = "property.id") @Resource(name = "property.id", required = false)
private String id; private String id;
@Resource @Resource

View File

@@ -53,7 +53,7 @@ public class ResourceTest {
props.put("property.id", "5555"); props.put("property.id", "5555");
props.put("property.desc", "my desc"); props.put("property.desc", "my desc");
factory.register(props); factory.register(props);
bservice = new BService("ffff"); bservice = new BService("ffff");
factory.register(bservice); //更新Resource池内name=""的BService资源, 同时ResourceFactory会自动更新aservice的bservice对象 factory.register(bservice); //更新Resource池内name=""的BService资源, 同时ResourceFactory会自动更新aservice的bservice对象
factory.inject(bservice); factory.inject(bservice);
@@ -68,7 +68,7 @@ class BService {
@Resource(name = "property.id") @Resource(name = "property.id")
private String id; private String id;
@Resource(name = "property.desc") @Resource(name = "property.desc", required = false)
private String desc; private String desc;
@Resource @Resource
@@ -126,10 +126,10 @@ class AService {
@Resource(name = "property.id") //property.开头的资源名允许String自动转换成primitive数值类型 @Resource(name = "property.id") //property.开头的资源名允许String自动转换成primitive数值类型
private int intid; private int intid;
@Resource(name = "bigint") @Resource(name = "bigint", required = false)
private BigInteger bigint; private BigInteger bigint;
@Resource(name = "seqid") @Resource(name = "seqid", required = false)
private int seqid; private int seqid;
@Resource @Resource