调整ResourceTypeLoader
This commit is contained in:
@@ -391,7 +391,9 @@ public final class Application {
|
||||
Field field,
|
||||
Object attachment) {
|
||||
try {
|
||||
field.set(srcObj, application);
|
||||
if (field != null) {
|
||||
field.set(srcObj, application);
|
||||
}
|
||||
return application;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Resource inject error", e);
|
||||
@@ -423,7 +425,9 @@ public final class Application {
|
||||
boolean serv =
|
||||
RESNAME_SERVER_RESFACTORY.equals(resourceName) || resourceName.equalsIgnoreCase("server");
|
||||
ResourceFactory rs = serv ? rf : (resourceName.isEmpty() ? application.resourceFactory : null);
|
||||
field.set(srcObj, rs);
|
||||
if (field != null) {
|
||||
field.set(srcObj, rs);
|
||||
}
|
||||
return rs;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Resource inject error", e);
|
||||
@@ -462,7 +466,9 @@ public final class Application {
|
||||
break;
|
||||
}
|
||||
}
|
||||
field.set(srcObj, server);
|
||||
if (field != null) {
|
||||
field.set(srcObj, server);
|
||||
}
|
||||
return server;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Resource inject error", e);
|
||||
@@ -501,7 +507,9 @@ public final class Application {
|
||||
break;
|
||||
}
|
||||
}
|
||||
field.set(srcObj, server);
|
||||
if (field != null) {
|
||||
field.set(srcObj, server);
|
||||
}
|
||||
return server;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Resource inject error", e);
|
||||
@@ -540,7 +548,9 @@ public final class Application {
|
||||
break;
|
||||
}
|
||||
}
|
||||
field.set(srcObj, server);
|
||||
if (field != null) {
|
||||
field.set(srcObj, server);
|
||||
}
|
||||
return server;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Resource inject error", e);
|
||||
@@ -578,7 +588,9 @@ public final class Application {
|
||||
builder.version(HttpClient.Version.HTTP_2);
|
||||
}
|
||||
java.net.http.HttpClient httpClient = builder.build();
|
||||
field.set(srcObj, httpClient);
|
||||
if (field != null) {
|
||||
field.set(srcObj, httpClient);
|
||||
}
|
||||
rf.inject(resourceName, httpClient, null); // 给其可能包含@Resource的字段赋值;
|
||||
rf.register(resourceName, java.net.http.HttpClient.class, httpClient);
|
||||
return httpClient;
|
||||
@@ -606,7 +618,9 @@ public final class Application {
|
||||
Object attachment) {
|
||||
try {
|
||||
WebClient httpClient = WebClient.create(workExecutor, clientAsyncGroup);
|
||||
field.set(srcObj, httpClient);
|
||||
if (field != null) {
|
||||
field.set(srcObj, httpClient);
|
||||
}
|
||||
rf.inject(resourceName, httpClient, null); // 给其可能包含@Resource的字段赋值;
|
||||
rf.register(resourceName, WebClient.class, httpClient);
|
||||
return httpClient;
|
||||
@@ -640,7 +654,9 @@ public final class Application {
|
||||
|| !Objects.equals(clusterAgent.getName(), resourceName)
|
||||
|| messageAgent.isRpcFirst()) {
|
||||
HttpRpcClient rpcClient = messageAgent.getHttpRpcClient();
|
||||
field.set(srcObj, rpcClient);
|
||||
if (field != null) {
|
||||
field.set(srcObj, rpcClient);
|
||||
}
|
||||
rf.inject(resourceName, rpcClient, null); // 给其可能包含@Resource的字段赋值;
|
||||
rf.register(resourceName, HttpRpcClient.class, rpcClient);
|
||||
return rpcClient;
|
||||
@@ -648,13 +664,17 @@ public final class Application {
|
||||
}
|
||||
if (clusterAgent == null) {
|
||||
HttpRpcClient rpcClient = new HttpLocalRpcClient(application, resourceName);
|
||||
field.set(srcObj, rpcClient);
|
||||
if (field != null) {
|
||||
field.set(srcObj, rpcClient);
|
||||
}
|
||||
rf.inject(resourceName, rpcClient, null); // 给其可能包含@Resource的字段赋值;
|
||||
rf.register(resourceName, HttpRpcClient.class, rpcClient);
|
||||
return rpcClient;
|
||||
}
|
||||
HttpRpcClient rpcClient = new HttpClusterRpcClient(application, resourceName, clusterAgent);
|
||||
field.set(srcObj, rpcClient);
|
||||
if (field != null) {
|
||||
field.set(srcObj, rpcClient);
|
||||
}
|
||||
rf.inject(resourceName, rpcClient, null); // 给其可能包含@Resource的字段赋值;
|
||||
rf.register(resourceName, HttpRpcClient.class, rpcClient);
|
||||
return rpcClient;
|
||||
|
||||
@@ -38,6 +38,18 @@ public abstract class ModuleEngine {
|
||||
this.environment = Objects.requireNonNull(application.getEnvironment());
|
||||
}
|
||||
|
||||
public final ResourceFactory getResourceFactory() {
|
||||
return resourceFactory;
|
||||
}
|
||||
|
||||
public final Environment getEnvironment() {
|
||||
return environment;
|
||||
}
|
||||
|
||||
public final Application getApplication() {
|
||||
return application;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断模块的配置项合并策略, 返回null表示模块不识别此配置项
|
||||
*
|
||||
|
||||
123
src/main/java/org/redkale/boot/NodeAutoServiceLoader.java
Normal file
123
src/main/java/org/redkale/boot/NodeAutoServiceLoader.java
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
package org.redkale.boot;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.redkale.annotation.AutoLoad;
|
||||
import org.redkale.asm.AsmMethodBoost;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.inject.ResourceTypeLoader;
|
||||
import org.redkale.mq.spi.MessageAgent;
|
||||
import org.redkale.net.sncp.Sncp;
|
||||
import org.redkale.service.Local;
|
||||
import org.redkale.service.Service;
|
||||
import org.redkale.util.Utility;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
class NodeAutoServiceLoader implements ResourceTypeLoader {
|
||||
|
||||
private final Logger logger = Logger.getLogger(getClass().getSimpleName());
|
||||
|
||||
private final NodeServer nodeServer;
|
||||
|
||||
public NodeAutoServiceLoader(NodeServer nodeServer) {
|
||||
this.nodeServer = nodeServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object load(
|
||||
ResourceFactory rf,
|
||||
String srcResourceName,
|
||||
final Object srcObj,
|
||||
final String resourceName,
|
||||
Field field,
|
||||
final Object attachment) {
|
||||
Application application = nodeServer.getApplication();
|
||||
final ResourceFactory appResFactory = application.getResourceFactory();
|
||||
Class<Service> serviceImplClass = Service.class;
|
||||
try {
|
||||
serviceImplClass = (Class) field.getType();
|
||||
if (serviceImplClass.getAnnotation(Local.class) == null) {
|
||||
return null;
|
||||
}
|
||||
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) {
|
||||
return null; // 远程模式不得注入 AutoLoad Service
|
||||
}
|
||||
boolean auto = true;
|
||||
AutoLoad al = serviceImplClass.getAnnotation(AutoLoad.class);
|
||||
if (al != null) {
|
||||
auto = al.value();
|
||||
}
|
||||
org.redkale.util.AutoLoad al2 = serviceImplClass.getAnnotation(org.redkale.util.AutoLoad.class);
|
||||
if (al2 != null) {
|
||||
auto = al2.value();
|
||||
}
|
||||
if (auto && !Utility.isAbstractOrInterface(serviceImplClass)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// ResourceFactory resfactory = (isSNCP() ? appResFactory : resourceFactory);
|
||||
Service service;
|
||||
if (Modifier.isFinal(serviceImplClass.getModifiers()) || Sncp.isComponent(serviceImplClass)) {
|
||||
service = (Service) serviceImplClass.getConstructor().newInstance();
|
||||
} else if (Utility.isAbstractOrInterface(serviceImplClass)) { // 没有具体实现类
|
||||
AsmMethodBoost methodBoost = application.createAsmMethodBoost(true, serviceImplClass);
|
||||
MessageAgent mqAgent = appResFactory.find("", MessageAgent.class);
|
||||
service = Sncp.createRemoteService(
|
||||
nodeServer.serverClassLoader,
|
||||
resourceName,
|
||||
serviceImplClass,
|
||||
methodBoost,
|
||||
appResFactory,
|
||||
application.getSncpRpcGroups(),
|
||||
nodeServer.sncpClient,
|
||||
mqAgent,
|
||||
null,
|
||||
null);
|
||||
} else {
|
||||
AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, serviceImplClass);
|
||||
service = Sncp.createLocalService(
|
||||
nodeServer.serverClassLoader,
|
||||
resourceName,
|
||||
serviceImplClass,
|
||||
methodBoost,
|
||||
appResFactory,
|
||||
application.getSncpRpcGroups(),
|
||||
nodeServer.sncpClient,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
}
|
||||
appResFactory.register(resourceName, serviceImplClass, service);
|
||||
|
||||
field.set(srcObj, service);
|
||||
rf.inject(resourceName, service, nodeServer); // 给其可能包含@Resource的字段赋值;
|
||||
if (!application.isCompileMode() && !Sncp.isRemote(service)) {
|
||||
service.init(null);
|
||||
}
|
||||
logger.info("Load Service(" + (Sncp.isRemote(service) ? "Remote" : "@Local") + " @AutoLoad service = "
|
||||
+ serviceImplClass.getSimpleName() + ", resourceName = '" + resourceName + "')");
|
||||
return service;
|
||||
} catch (Exception e) {
|
||||
logger.log(
|
||||
Level.SEVERE,
|
||||
"Load @AutoLoad(false) Service inject " + serviceImplClass + " to " + srcObj + " error",
|
||||
e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type resourceType() {
|
||||
return Service.class;
|
||||
}
|
||||
}
|
||||
162
src/main/java/org/redkale/boot/NodeExpectServiceLoader.java
Normal file
162
src/main/java/org/redkale/boot/NodeExpectServiceLoader.java
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
package org.redkale.boot;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.redkale.annotation.Priority;
|
||||
import org.redkale.asm.AsmMethodBoost;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.inject.ResourceTypeLoader;
|
||||
import org.redkale.mq.spi.MessageAgent;
|
||||
import org.redkale.net.http.WebSocketServlet;
|
||||
import org.redkale.net.sncp.Sncp;
|
||||
import org.redkale.net.sncp.SncpRpcGroups;
|
||||
import org.redkale.service.Service;
|
||||
import org.redkale.util.RedkaleClassLoader;
|
||||
import org.redkale.util.RedkaleException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
class NodeExpectServiceLoader implements ResourceTypeLoader {
|
||||
|
||||
private final Logger logger = Logger.getLogger(getClass().getSimpleName());
|
||||
|
||||
private final NodeServer nodeServer;
|
||||
|
||||
private final Class type;
|
||||
|
||||
private final Class<? extends Service> serviceImplClass;
|
||||
|
||||
private final AtomicInteger serviceCount;
|
||||
|
||||
private final SncpRpcGroups rpcGroups;
|
||||
|
||||
private final ClassFilter.FilterEntry<? extends Service> entry;
|
||||
|
||||
private final String group;
|
||||
|
||||
private final boolean localMode;
|
||||
|
||||
public NodeExpectServiceLoader(
|
||||
NodeServer nodeServer,
|
||||
Class type,
|
||||
Class<? extends Service> serviceImplClass,
|
||||
AtomicInteger serviceCount,
|
||||
SncpRpcGroups rpcGroups,
|
||||
ClassFilter.FilterEntry<? extends Service> entry,
|
||||
String group,
|
||||
boolean localMode) {
|
||||
this.nodeServer = nodeServer;
|
||||
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 {
|
||||
Application application = nodeServer.getApplication();
|
||||
final ResourceFactory resourceFactory = nodeServer.getResourceFactory();
|
||||
final ResourceFactory appResourceFactory = application.getResourceFactory();
|
||||
ResourceFactory regFactory = nodeServer.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 = nodeServer.getMessageAgent(entry.getProperty());
|
||||
Service service;
|
||||
if (Sncp.isComponent(serviceImplClass)) { // Component
|
||||
RedkaleClassLoader.putReflectionPublicConstructors(serviceImplClass, serviceImplClass.getName());
|
||||
if (!nodeServer.acceptsComponent(serviceImplClass)) {
|
||||
return null;
|
||||
}
|
||||
service = serviceImplClass.getDeclaredConstructor().newInstance();
|
||||
} else if (srcObj instanceof WebSocketServlet || localMode) { // 本地模式
|
||||
AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, serviceImplClass);
|
||||
service = Sncp.createLocalService(
|
||||
nodeServer.serverClassLoader,
|
||||
resourceName,
|
||||
serviceImplClass,
|
||||
methodBoost,
|
||||
appResourceFactory,
|
||||
rpcGroups,
|
||||
nodeServer.sncpClient,
|
||||
mqAgent,
|
||||
group,
|
||||
entry.getProperty());
|
||||
} else {
|
||||
AsmMethodBoost methodBoost = application.createAsmMethodBoost(true, serviceImplClass);
|
||||
service = Sncp.createRemoteService(
|
||||
nodeServer.serverClassLoader,
|
||||
resourceName,
|
||||
serviceImplClass,
|
||||
methodBoost,
|
||||
appResourceFactory,
|
||||
rpcGroups,
|
||||
nodeServer.sncpClient,
|
||||
mqAgent,
|
||||
group,
|
||||
entry.getProperty());
|
||||
}
|
||||
final Class restype = Sncp.getResourceType(service);
|
||||
if (rf.find(resourceName, restype) == null) {
|
||||
regFactory.register(resourceName, restype, service);
|
||||
} else if (nodeServer.isSNCP() && !entry.isAutoload()) {
|
||||
throw new RedkaleException(restype.getSimpleName() + "(class:" + serviceImplClass.getName() + ", name:"
|
||||
+ resourceName + ", group:" + group + ") is repeat.");
|
||||
}
|
||||
if (Sncp.isRemote(service)) {
|
||||
nodeServer.remoteServices.add(service);
|
||||
if (mqAgent != null) {
|
||||
nodeServer.sncpRemoteAgents.put(mqAgent.getName(), mqAgent);
|
||||
}
|
||||
} else {
|
||||
if (field != null) {
|
||||
rf.inject(resourceName, service); // 动态加载的Service也存在按需加载的注入资源
|
||||
}
|
||||
nodeServer.localServices.add(service);
|
||||
if (!Sncp.isComponent(service)) {
|
||||
nodeServer.servletServices.add(service);
|
||||
}
|
||||
}
|
||||
serviceCount.incrementAndGet();
|
||||
return service;
|
||||
} catch (Exception e) {
|
||||
throw e instanceof RuntimeException ? (RuntimeException) e : new RedkaleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type resourceType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,6 @@
|
||||
*/
|
||||
package org.redkale.boot;
|
||||
|
||||
import static org.redkale.boot.Application.RESNAME_SNCP_ADDRESS;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.*;
|
||||
import java.net.*;
|
||||
@@ -16,11 +14,8 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Stream;
|
||||
import org.redkale.annotation.*;
|
||||
import org.redkale.asm.AsmMethodBoost;
|
||||
import org.redkale.boot.ClassFilter.FilterEntry;
|
||||
import org.redkale.cluster.spi.ClusterAgent;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.inject.ResourceTypeLoader;
|
||||
import org.redkale.mq.spi.MessageAgent;
|
||||
import org.redkale.net.*;
|
||||
import org.redkale.net.http.*;
|
||||
@@ -124,7 +119,7 @@ public class NodeHttpServer extends NodeServer {
|
||||
@Override
|
||||
protected void loadService(ClassFilter<? extends Service> serviceFilter) throws Exception {
|
||||
super.loadService(serviceFilter);
|
||||
initWebSocketService();
|
||||
resourceFactory.register(new NodeWebSocketNodeLoader(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -142,105 +137,6 @@ public class NodeHttpServer extends NodeServer {
|
||||
}
|
||||
}
|
||||
|
||||
private void initWebSocketService() {
|
||||
final NodeServer self = this;
|
||||
final ResourceFactory regFactory = application.getResourceFactory();
|
||||
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);
|
||||
throw e instanceof RuntimeException ? (RuntimeException) e : new RedkaleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type resourceType() {
|
||||
return WebSocketNode.class;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void loadHttpFilter(final ClassFilter<? extends Filter> classFilter) throws Exception {
|
||||
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
*/
|
||||
package org.redkale.boot;
|
||||
|
||||
import static org.redkale.boot.Application.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.*;
|
||||
@@ -18,19 +16,15 @@ import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.*;
|
||||
import org.redkale.annotation.*;
|
||||
import org.redkale.annotation.AutoLoad;
|
||||
import org.redkale.annotation.Command;
|
||||
import org.redkale.asm.AsmMethodBoost;
|
||||
import static org.redkale.boot.Application.*;
|
||||
import org.redkale.boot.ClassFilter.FilterEntry;
|
||||
import org.redkale.cluster.spi.ClusterAgent;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.inject.ResourceTypeLoader;
|
||||
import org.redkale.mq.spi.MessageAgent;
|
||||
import org.redkale.net.*;
|
||||
import org.redkale.net.Filter;
|
||||
import org.redkale.net.client.ClientAddress;
|
||||
import org.redkale.net.http.*;
|
||||
import org.redkale.net.http.WebSocketNodeService;
|
||||
import org.redkale.net.sncp.*;
|
||||
import org.redkale.service.*;
|
||||
import org.redkale.source.*;
|
||||
@@ -202,7 +196,12 @@ public abstract class NodeServer {
|
||||
1000);
|
||||
}
|
||||
|
||||
registerResTypeLoader(); // 给DataSource、CacheSource注册依赖注入时的监听回调事件。
|
||||
// --------------------- 注册 Local AutoLoad(false) Service ---------------------
|
||||
resourceFactory.register(new NodeAutoServiceLoader(this));
|
||||
// ----------------------------- 注册 WebSocketNode -----------------------------
|
||||
resourceFactory.register(new NodeWebSocketNodeLoader(this));
|
||||
|
||||
// 过滤类
|
||||
String interceptorClass = this.serverConf.getValue("interceptor", "");
|
||||
if (!interceptorClass.isEmpty()) {
|
||||
Class clazz = serverClassLoader.loadClass(interceptorClass);
|
||||
@@ -265,305 +264,6 @@ public abstract class NodeServer {
|
||||
|
||||
protected abstract void loadServlet(ClassFilter<? extends Servlet> servletFilter) throws Exception;
|
||||
|
||||
private void registerResTypeLoader() {
|
||||
// --------------------- 注册 Local AutoLoad(false) Service ---------------------
|
||||
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();
|
||||
resourceFactory.register(new ResourceTypeLoader() {
|
||||
@Override
|
||||
public Object load(
|
||||
ResourceFactory rf,
|
||||
String srcResourceName,
|
||||
final Object srcObj,
|
||||
final String resourceName,
|
||||
Field field,
|
||||
final Object attachment) {
|
||||
try {
|
||||
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) {
|
||||
return null; // 远程模式不得注入
|
||||
}
|
||||
Service nodeService = rf.find(resourceName, WebSocketNode.class);
|
||||
if (nodeService == null) {
|
||||
final HashSet<String> groups = new HashSet<>();
|
||||
if (groups.isEmpty() && isSNCP() && NodeServer.this.sncpGroup != null) {
|
||||
groups.add(NodeServer.this.sncpGroup);
|
||||
}
|
||||
AsmMethodBoost methodBoost =
|
||||
application.createAsmMethodBoost(false, WebSocketNodeService.class);
|
||||
nodeService = Sncp.createLocalService(
|
||||
serverClassLoader,
|
||||
resourceName,
|
||||
WebSocketNodeService.class,
|
||||
methodBoost,
|
||||
application.getResourceFactory(),
|
||||
application.getSncpRpcGroups(),
|
||||
sncpClient,
|
||||
null,
|
||||
(String) null,
|
||||
(AnyValue) null);
|
||||
(isSNCP() ? appResFactory : resourceFactory)
|
||||
.register(resourceName, WebSocketNode.class, nodeService);
|
||||
((org.redkale.net.http.WebSocketNodeService) nodeService).setName(resourceName);
|
||||
}
|
||||
resourceFactory.inject(resourceName, nodeService, self);
|
||||
field.set(srcObj, nodeService);
|
||||
if (Sncp.isRemote(nodeService)) {
|
||||
remoteServices.add(nodeService);
|
||||
} else {
|
||||
rf.inject(resourceName, nodeService); // 动态加载的Service也存在按需加载的注入资源
|
||||
localServices.add(nodeService);
|
||||
if (!Sncp.isComponent(nodeService)) {
|
||||
servletServices.add(nodeService);
|
||||
}
|
||||
}
|
||||
return nodeService;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "WebSocketNode inject error", e);
|
||||
throw e instanceof RuntimeException ? (RuntimeException) e : new RedkaleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type resourceType() {
|
||||
return WebSocketNode.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean autoNone() {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Service.class的ResourceTypeLoader
|
||||
private Object loadResourceService(
|
||||
ResourceFactory rf,
|
||||
String srcResourceName,
|
||||
Object srcObj,
|
||||
String resourceName,
|
||||
Field field,
|
||||
Object attachment) {
|
||||
final NodeServer self = this;
|
||||
final ResourceFactory appResFactory = application.getResourceFactory();
|
||||
Class<Service> serviceImplClass = Service.class;
|
||||
try {
|
||||
serviceImplClass = (Class) field.getType();
|
||||
if (serviceImplClass.getAnnotation(Local.class) == null) {
|
||||
return null;
|
||||
}
|
||||
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) {
|
||||
return null; // 远程模式不得注入 AutoLoad Service
|
||||
}
|
||||
boolean auto = true;
|
||||
AutoLoad al = serviceImplClass.getAnnotation(AutoLoad.class);
|
||||
if (al != null) {
|
||||
auto = al.value();
|
||||
}
|
||||
org.redkale.util.AutoLoad al2 = serviceImplClass.getAnnotation(org.redkale.util.AutoLoad.class);
|
||||
if (al2 != null) {
|
||||
auto = al2.value();
|
||||
}
|
||||
if (auto && !Utility.isAbstractOrInterface(serviceImplClass)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// ResourceFactory resfactory = (isSNCP() ? appResFactory : resourceFactory);
|
||||
Service service;
|
||||
if (Modifier.isFinal(serviceImplClass.getModifiers()) || Sncp.isComponent(serviceImplClass)) {
|
||||
service = (Service) serviceImplClass.getConstructor().newInstance();
|
||||
} else if (Utility.isAbstractOrInterface(serviceImplClass)) { // 没有具体实现类
|
||||
AsmMethodBoost methodBoost = application.createAsmMethodBoost(true, serviceImplClass);
|
||||
MessageAgent mqAgent = appResFactory.find("", MessageAgent.class);
|
||||
service = Sncp.createRemoteService(
|
||||
serverClassLoader,
|
||||
resourceName,
|
||||
serviceImplClass,
|
||||
methodBoost,
|
||||
appResFactory,
|
||||
application.getSncpRpcGroups(),
|
||||
this.sncpClient,
|
||||
mqAgent,
|
||||
null,
|
||||
null);
|
||||
} else {
|
||||
AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, serviceImplClass);
|
||||
service = Sncp.createLocalService(
|
||||
serverClassLoader,
|
||||
resourceName,
|
||||
serviceImplClass,
|
||||
methodBoost,
|
||||
appResFactory,
|
||||
application.getSncpRpcGroups(),
|
||||
sncpClient,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
}
|
||||
appResFactory.register(resourceName, serviceImplClass, service);
|
||||
|
||||
field.set(srcObj, service);
|
||||
rf.inject(resourceName, service, self); // 给其可能包含@Resource的字段赋值;
|
||||
if (!application.isCompileMode() && !Sncp.isRemote(service)) {
|
||||
service.init(null);
|
||||
}
|
||||
logger.info("Load Service(" + (Sncp.isRemote(service) ? "Remote" : "@Local") + " @AutoLoad service = "
|
||||
+ serviceImplClass.getSimpleName() + ", resourceName = '" + resourceName + "')");
|
||||
return service;
|
||||
} catch (Exception e) {
|
||||
logger.log(
|
||||
Level.SEVERE,
|
||||
"Load @AutoLoad(false) Service inject " + serviceImplClass + " to " + srcObj + " error",
|
||||
e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private class ExpectServiceLoader implements ResourceTypeLoader {
|
||||
|
||||
private final Class type;
|
||||
|
||||
private final Class<? extends Service> serviceImplClass;
|
||||
|
||||
private final AtomicInteger serviceCount;
|
||||
|
||||
private final SncpRpcGroups rpcGroups;
|
||||
|
||||
private final FilterEntry<? extends Service> entry;
|
||||
|
||||
private final String group;
|
||||
|
||||
private final boolean localMode;
|
||||
|
||||
public ExpectServiceLoader(
|
||||
Class type,
|
||||
Class<? extends Service> serviceImplClass,
|
||||
AtomicInteger serviceCount,
|
||||
SncpRpcGroups rpcGroups,
|
||||
FilterEntry<? extends Service> 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 (Exception e) {
|
||||
throw e instanceof RuntimeException ? (RuntimeException) e : new RedkaleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type resourceType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void loadService(ClassFilter<? extends Service> serviceFilter) throws Exception {
|
||||
Objects.requireNonNull(serviceFilter);
|
||||
@@ -618,12 +318,12 @@ public abstract class NodeServer {
|
||||
if (entry.isExpect()) {
|
||||
Class t = ResourceFactory.getResourceType(entry.getType());
|
||||
if (resourceFactory.findResourceTypeLoader(t) == null) {
|
||||
resourceFactory.register(new ExpectServiceLoader(
|
||||
t, serviceImplClass, serviceCount, rpcGroups, entry, group, localMode));
|
||||
resourceFactory.register(new NodeExpectServiceLoader(
|
||||
this, t, serviceImplClass, serviceCount, rpcGroups, entry, group, localMode));
|
||||
}
|
||||
} else {
|
||||
ExpectServiceLoader resourceLoader = new ExpectServiceLoader(
|
||||
serviceImplClass, serviceImplClass, serviceCount, rpcGroups, entry, group, localMode);
|
||||
NodeExpectServiceLoader resourceLoader = new NodeExpectServiceLoader(
|
||||
this, serviceImplClass, serviceImplClass, serviceCount, rpcGroups, entry, group, localMode);
|
||||
resourceLoader.load(resourceFactory, null, null, entry.getName(), null, false);
|
||||
}
|
||||
}
|
||||
|
||||
206
src/main/java/org/redkale/boot/NodeWebSocketNodeLoader.java
Normal file
206
src/main/java/org/redkale/boot/NodeWebSocketNodeLoader.java
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
package org.redkale.boot;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.HashSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.redkale.asm.AsmMethodBoost;
|
||||
import static org.redkale.boot.Application.RESNAME_SNCP_ADDRESS;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.inject.ResourceTypeLoader;
|
||||
import org.redkale.mq.spi.MessageAgent;
|
||||
import org.redkale.net.http.WebSocketNode;
|
||||
import org.redkale.net.http.WebSocketNodeService;
|
||||
import org.redkale.net.http.WebSocketServlet;
|
||||
import org.redkale.net.sncp.Sncp;
|
||||
import org.redkale.service.Service;
|
||||
import org.redkale.util.AnyValue;
|
||||
import org.redkale.util.RedkaleClassLoader;
|
||||
import org.redkale.util.RedkaleException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
class NodeWebSocketNodeLoader implements ResourceTypeLoader {
|
||||
|
||||
private final Logger logger = Logger.getLogger(getClass().getSimpleName());
|
||||
|
||||
private final NodeServer nodeServer;
|
||||
|
||||
public NodeWebSocketNodeLoader(NodeServer nodeServer) {
|
||||
this.nodeServer = nodeServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object load(
|
||||
ResourceFactory rf,
|
||||
String srcResourceName,
|
||||
Object srcObj,
|
||||
String resourceName,
|
||||
Field field,
|
||||
Object attachment) {
|
||||
if (srcObj instanceof WebSocketServlet) {
|
||||
return loadInServlet(rf, srcResourceName, srcObj, resourceName, field, attachment);
|
||||
} else {
|
||||
return loadInService(rf, srcResourceName, srcObj, resourceName, field, attachment);
|
||||
}
|
||||
}
|
||||
|
||||
private Object loadInService(
|
||||
ResourceFactory rf,
|
||||
String srcResourceName,
|
||||
Object srcObj,
|
||||
String resourceName,
|
||||
Field field,
|
||||
Object attachment) {
|
||||
try {
|
||||
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) {
|
||||
return null; // 远程模式不得注入
|
||||
}
|
||||
Application application = nodeServer.getApplication();
|
||||
final ResourceFactory appResFactory = application.getResourceFactory();
|
||||
final ResourceFactory resourceFactory = nodeServer.getResourceFactory();
|
||||
Service nodeService = rf.find(resourceName, WebSocketNode.class);
|
||||
if (nodeService == null) {
|
||||
final HashSet<String> groups = new HashSet<>();
|
||||
if (groups.isEmpty() && nodeServer.isSNCP() && nodeServer.sncpGroup != null) {
|
||||
groups.add(nodeServer.sncpGroup);
|
||||
}
|
||||
AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, WebSocketNodeService.class);
|
||||
nodeService = Sncp.createLocalService(
|
||||
nodeServer.serverClassLoader,
|
||||
resourceName,
|
||||
WebSocketNodeService.class,
|
||||
methodBoost,
|
||||
application.getResourceFactory(),
|
||||
application.getSncpRpcGroups(),
|
||||
nodeServer.sncpClient,
|
||||
null,
|
||||
(String) null,
|
||||
(AnyValue) null);
|
||||
(nodeServer.isSNCP() ? appResFactory : resourceFactory)
|
||||
.register(resourceName, WebSocketNode.class, nodeService);
|
||||
((org.redkale.net.http.WebSocketNodeService) nodeService).setName(resourceName);
|
||||
}
|
||||
resourceFactory.inject(resourceName, nodeService, nodeServer);
|
||||
if (field != null) {
|
||||
field.set(srcObj, nodeService);
|
||||
}
|
||||
if (Sncp.isRemote(nodeService)) {
|
||||
nodeServer.remoteServices.add(nodeService);
|
||||
} else {
|
||||
rf.inject(resourceName, nodeService); // 动态加载的Service也存在按需加载的注入资源
|
||||
nodeServer.localServices.add(nodeService);
|
||||
if (!Sncp.isComponent(nodeService)) {
|
||||
nodeServer.servletServices.add(nodeService);
|
||||
}
|
||||
}
|
||||
return nodeService;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "WebSocketNode inject error", e);
|
||||
throw e instanceof RuntimeException ? (RuntimeException) e : new RedkaleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private Object loadInServlet(
|
||||
ResourceFactory rf,
|
||||
String srcResourceName,
|
||||
Object srcObj,
|
||||
String resourceName,
|
||||
Field field,
|
||||
Object attachment) { // 主要用于单点的服务
|
||||
try {
|
||||
if (!(srcObj instanceof WebSocketServlet)) {
|
||||
return null;
|
||||
}
|
||||
Application application = nodeServer.getApplication();
|
||||
final ResourceFactory regFactory = application.getResourceFactory();
|
||||
final ResourceFactory resourceFactory = nodeServer.getResourceFactory();
|
||||
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(
|
||||
nodeServer.serverClassLoader,
|
||||
resourceName,
|
||||
WebSocketNodeService.class,
|
||||
methodBoost,
|
||||
application.getResourceFactory(),
|
||||
application.getSncpRpcGroups(),
|
||||
nodeServer.sncpClient,
|
||||
messageAgent,
|
||||
(String) null,
|
||||
(AnyValue) null);
|
||||
regFactory.register(resourceName, WebSocketNode.class, nodeService);
|
||||
}
|
||||
resourceFactory.inject(resourceName, nodeService, nodeServer);
|
||||
if (field != null) {
|
||||
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);
|
||||
throw e instanceof RuntimeException ? (RuntimeException) e : new RedkaleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type resourceType() {
|
||||
return WebSocketNode.class;
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,7 @@ public class CachedAction {
|
||||
}
|
||||
|
||||
void init(ResourceFactory resourceFactory, Object service) {
|
||||
this.manager = resourceFactory.find(cached.getManager(), CachedManager.class);
|
||||
this.manager = resourceFactory.load(cached.getManager(), CachedManager.class);
|
||||
String key = environment.getPropertyValue(cached.getKey());
|
||||
this.templetKey = key;
|
||||
if (key.startsWith("@")) { // 动态加载缓存key生成器
|
||||
|
||||
@@ -233,6 +233,7 @@ public class CachedAsmMethodBoost extends AsmMethodBoost {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
actionMap.forEach((field, action) -> {
|
||||
try {
|
||||
resourceFactory.inject(action);
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
package org.redkale.cached.spi;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.inject.ResourceTypeLoader;
|
||||
import org.redkale.service.Service;
|
||||
import org.redkale.util.RedkaleException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
class CachedKeyGeneratorLoader implements ResourceTypeLoader {
|
||||
|
||||
private final Logger logger = Logger.getLogger(getClass().getSimpleName());
|
||||
|
||||
private final CachedModuleEngine engine;
|
||||
|
||||
private final Map<String, CachedKeyGenerator> generatorMap = new ConcurrentHashMap<>();
|
||||
|
||||
public CachedKeyGeneratorLoader(CachedModuleEngine engine) {
|
||||
this.engine = engine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object load(
|
||||
ResourceFactory rf,
|
||||
String srcResourceName,
|
||||
Object srcObj,
|
||||
String resourceName,
|
||||
Field field,
|
||||
Object attachment) {
|
||||
try {
|
||||
CachedKeyGenerator generator = rf.find(resourceName, CachedKeyGenerator.class);
|
||||
if (generator != null) {
|
||||
return generator;
|
||||
}
|
||||
generator = generatorMap.computeIfAbsent(resourceName, n -> {
|
||||
for (CachedKeyGenerator instance : ServiceLoader.load(
|
||||
CachedKeyGenerator.class, engine.getApplication().getClassLoader())) {
|
||||
if (Objects.equals(n, instance.name())) {
|
||||
rf.inject(instance);
|
||||
if (instance instanceof Service) {
|
||||
((Service) instance).init(null);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
if (generator != null) {
|
||||
rf.register(resourceName, CachedKeyGenerator.class, generator);
|
||||
if (field != null) {
|
||||
field.set(srcObj, generator);
|
||||
}
|
||||
}
|
||||
return generator;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, CachedKeyGenerator.class.getSimpleName() + " inject error", e);
|
||||
throw e instanceof RuntimeException ? (RuntimeException) e : new RedkaleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type resourceType() {
|
||||
return CachedKeyGenerator.class;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
package org.redkale.cached.spi;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.redkale.cached.CachedManager;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.inject.ResourceTypeLoader;
|
||||
import org.redkale.service.Service;
|
||||
import org.redkale.util.AnyValue;
|
||||
import org.redkale.util.RedkaleException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
class CachedManagerLoader implements ResourceTypeLoader {
|
||||
|
||||
private final Logger logger = Logger.getLogger(getClass().getSimpleName());
|
||||
private final CachedModuleEngine engine;
|
||||
private Map<String, AnyValue> configMap;
|
||||
|
||||
public CachedManagerLoader(CachedModuleEngine engine, Map<String, AnyValue> configMap) {
|
||||
this.engine = engine;
|
||||
this.configMap = configMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object load(
|
||||
ResourceFactory rf,
|
||||
String srcResourceName,
|
||||
Object srcObj,
|
||||
String resourceName,
|
||||
Field field,
|
||||
Object attachment) {
|
||||
try {
|
||||
CachedManager manager = rf.find(resourceName, CachedManager.class);
|
||||
if (manager != null) {
|
||||
return manager;
|
||||
}
|
||||
AnyValue config = configMap.get(resourceName);
|
||||
if (config == null) {
|
||||
throw new RedkaleException(
|
||||
"Not found " + CachedManager.class.getSimpleName() + "(name='" + resourceName + "') config");
|
||||
}
|
||||
manager = engine.createManager(config);
|
||||
if (manager != null) {
|
||||
rf.register(resourceName, CachedManager.class, manager);
|
||||
engine.cacheManagerMap.put(resourceName, new CachedModuleEngine.ManagerEntity(manager, config));
|
||||
if (!engine.getApplication().isCompileMode()) {
|
||||
rf.inject(manager);
|
||||
if (manager instanceof Service) {
|
||||
((Service) manager).init(config);
|
||||
}
|
||||
logger.info("Load " + CachedManager.class.getSimpleName() + " (type="
|
||||
+ manager.getClass().getSimpleName() + ", resourceName='"
|
||||
+ resourceName + "', schema='"
|
||||
+ manager.getSchema() + "')");
|
||||
}
|
||||
if (field != null) {
|
||||
field.set(srcObj, manager);
|
||||
}
|
||||
}
|
||||
return manager;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, CachedManager.class.getSimpleName() + " inject error", e);
|
||||
throw e instanceof RuntimeException ? (RuntimeException) e : new RedkaleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type resourceType() {
|
||||
return CachedManager.class;
|
||||
}
|
||||
}
|
||||
@@ -117,16 +117,16 @@ public class CachedManagerService implements CachedManager, Service {
|
||||
this.schema = conf.getValue("schema", DEFAULT_SCHEMA);
|
||||
if (this.enabled) {
|
||||
this.localSource.init(conf);
|
||||
String remoteSourceName = conf.getValue("remote");
|
||||
String remoteSourceName = conf.getValue("remote", "");
|
||||
if (remoteSource == null && remoteSourceName != null) {
|
||||
this.broadcastable = conf.getBoolValue("broadcastable", true);
|
||||
CacheSource source = application.loadCacheSource(remoteSourceName, false);
|
||||
if (source == null) {
|
||||
if (source == null && !remoteSourceName.isEmpty()) {
|
||||
throw new RedkaleException("Not found CacheSource '" + remoteSourceName + "'");
|
||||
}
|
||||
this.remoteSource = source;
|
||||
this.broadcastable = conf.getBoolValue("broadcastable", true);
|
||||
}
|
||||
if (remoteSource != null) {
|
||||
if (remoteSource != null && this.broadcastable) {
|
||||
this.remoteListener = new CacheRemoteListener();
|
||||
this.remoteSource.subscribe(CachedEventMessage.class, remoteListener, getChannelTopic());
|
||||
}
|
||||
|
||||
@@ -3,26 +3,19 @@
|
||||
*/
|
||||
package org.redkale.cached.spi;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import org.redkale.asm.AsmMethodBoost;
|
||||
import org.redkale.boot.Application;
|
||||
import org.redkale.boot.ModuleEngine;
|
||||
import org.redkale.cached.CachedManager;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.inject.ResourceTypeLoader;
|
||||
import org.redkale.service.Service;
|
||||
import org.redkale.util.AnyValue;
|
||||
import org.redkale.util.AnyValueWriter;
|
||||
import org.redkale.util.InstanceProvider;
|
||||
import org.redkale.util.RedkaleClassLoader;
|
||||
import org.redkale.util.RedkaleException;
|
||||
@@ -40,7 +33,7 @@ public class CachedModuleEngine extends ModuleEngine {
|
||||
protected static final String CONFIG_NAME = "cached";
|
||||
|
||||
// 全局缓存管理器
|
||||
private ConcurrentHashMap<String, ManagerEntity> cacheManagerMap = new ConcurrentHashMap<>();
|
||||
protected ConcurrentHashMap<String, ManagerEntity> cacheManagerMap = new ConcurrentHashMap<>();
|
||||
|
||||
public CachedModuleEngine(Application application) {
|
||||
super(application);
|
||||
@@ -81,7 +74,7 @@ public class CachedModuleEngine extends ModuleEngine {
|
||||
// 设置缓存管理器
|
||||
AnyValue[] configs = application.getAppConfig().getAnyValues(CONFIG_NAME);
|
||||
if (configs == null || configs.length == 0) {
|
||||
configs = new AnyValue[] {new AnyValueWriter()};
|
||||
configs = new AnyValue[] {AnyValue.create()};
|
||||
}
|
||||
Map<String, AnyValue> configMap = new HashMap<>();
|
||||
for (AnyValue config : configs) {
|
||||
@@ -92,94 +85,8 @@ public class CachedModuleEngine extends ModuleEngine {
|
||||
}
|
||||
configMap.put(name, config);
|
||||
}
|
||||
this.resourceFactory.register(new ResourceTypeLoader() {
|
||||
|
||||
@Override
|
||||
public Object load(
|
||||
ResourceFactory rf,
|
||||
String srcResourceName,
|
||||
Object srcObj,
|
||||
String resourceName,
|
||||
Field field,
|
||||
Object attachment) {
|
||||
try {
|
||||
CachedManager manager = rf.find(resourceName, CachedManager.class);
|
||||
if (manager != null) {
|
||||
return manager;
|
||||
}
|
||||
AnyValue config = configMap.get(resourceName);
|
||||
if (config == null) {
|
||||
throw new RedkaleException("Not found " + CachedManager.class.getSimpleName() + "(name='"
|
||||
+ resourceName + "') config");
|
||||
}
|
||||
manager = createManager(config);
|
||||
if (manager != null) {
|
||||
rf.register(resourceName, CachedManager.class, manager);
|
||||
cacheManagerMap.put(resourceName, new ManagerEntity(manager, config));
|
||||
if (!application.isCompileMode()) {
|
||||
rf.inject(manager);
|
||||
if (manager instanceof Service) {
|
||||
((Service) manager).init(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
return manager;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, CachedManager.class.getSimpleName() + " inject error", e);
|
||||
throw e instanceof RuntimeException ? (RuntimeException) e : new RedkaleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type resourceType() {
|
||||
return CachedManager.class;
|
||||
}
|
||||
});
|
||||
|
||||
ConcurrentHashMap<String, CachedKeyGenerator> generatorMap = new ConcurrentHashMap<>();
|
||||
this.resourceFactory.register(new ResourceTypeLoader() {
|
||||
|
||||
@Override
|
||||
public Object load(
|
||||
ResourceFactory rf,
|
||||
String srcResourceName,
|
||||
Object srcObj,
|
||||
String resourceName,
|
||||
Field field,
|
||||
Object attachment) {
|
||||
try {
|
||||
CachedKeyGenerator generator = rf.find(resourceName, CachedKeyGenerator.class);
|
||||
if (generator != null) {
|
||||
return generator;
|
||||
}
|
||||
generator = generatorMap.computeIfAbsent(resourceName, n -> {
|
||||
for (CachedKeyGenerator instance :
|
||||
ServiceLoader.load(CachedKeyGenerator.class, application.getClassLoader())) {
|
||||
if (Objects.equals(n, instance.name())) {
|
||||
rf.inject(instance);
|
||||
if (instance instanceof Service) {
|
||||
((Service) instance).init(null);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
if (generator != null) {
|
||||
rf.register(resourceName, CachedKeyGenerator.class, generator);
|
||||
}
|
||||
return generator;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, CachedKeyGenerator.class.getSimpleName() + " inject error", e);
|
||||
throw e instanceof RuntimeException ? (RuntimeException) e : new RedkaleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type resourceType() {
|
||||
return CachedKeyGenerator.class;
|
||||
}
|
||||
});
|
||||
this.resourceFactory.register(new CachedManagerLoader(this, configMap));
|
||||
this.resourceFactory.register(new CachedKeyGeneratorLoader(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,7 +105,7 @@ public class CachedModuleEngine extends ModuleEngine {
|
||||
}
|
||||
}
|
||||
|
||||
private CachedManager createManager(AnyValue conf) {
|
||||
protected CachedManager createManager(AnyValue conf) {
|
||||
Iterator<CachedManagerProvider> it = ServiceLoader.load(
|
||||
CachedManagerProvider.class, application.getClassLoader())
|
||||
.iterator();
|
||||
|
||||
@@ -686,6 +686,32 @@ public final class ResourceFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
public <A> A load(Class<? extends A> clazz) {
|
||||
return load("", clazz);
|
||||
}
|
||||
|
||||
public <A> A load(String name, Type clazz) {
|
||||
A val = find(name, clazz);
|
||||
if (val == null) {
|
||||
ResourceTypeLoader loader = findResourceTypeLoader(clazz);
|
||||
if (loader != null) {
|
||||
val = (A) loader.load(this, null, null, name, null, null);
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
public <A> A load(String name, Class<? extends A> clazz) {
|
||||
A val = find(name, clazz);
|
||||
if (val == null) {
|
||||
ResourceTypeLoader loader = findResourceTypeLoader(clazz);
|
||||
if (loader != null) {
|
||||
val = (A) loader.load(this, null, null, name, null, null);
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
public <A> List<A> query(Class<? extends A> clazz) {
|
||||
return query(new ArrayList<>(), clazz);
|
||||
}
|
||||
@@ -1097,7 +1123,7 @@ public final class ResourceFactory {
|
||||
return parent == null ? null : parent.findResourceTypeLoader(clazz);
|
||||
}
|
||||
|
||||
public ResourceTypeLoader findTypeLoader(Type ft, Field field) {
|
||||
public ResourceTypeLoader findTypeLoader(Type ft, @Nullable Field field) {
|
||||
ResourceTypeLoader it = this.findMatchTypeLoader(ft, field);
|
||||
return it == null ? findRegxTypeLoader(ft, field) : it;
|
||||
}
|
||||
@@ -1109,7 +1135,7 @@ public final class ResourceFactory {
|
||||
return parent.parentRoot();
|
||||
}
|
||||
|
||||
private ResourceTypeLoader findMatchTypeLoader(Type ft, Field field) {
|
||||
private ResourceTypeLoader findMatchTypeLoader(Type ft, @Nullable Field field) {
|
||||
ResourceTypeLoader it = this.resTypeLoaderMap.get(ft);
|
||||
if (it == null && field != null) {
|
||||
it = this.resTypeLoaderMap.get(field.getType());
|
||||
@@ -1120,7 +1146,7 @@ public final class ResourceFactory {
|
||||
return parent == null ? null : parent.findMatchTypeLoader(ft, field);
|
||||
}
|
||||
|
||||
private ResourceTypeLoader findRegxTypeLoader(Type ft, Field field) {
|
||||
private ResourceTypeLoader findRegxTypeLoader(Type ft, @Nullable Field field) {
|
||||
if (field == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ package org.redkale.inject;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
import org.redkale.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* 自定义注入加载器
|
||||
@@ -14,18 +15,38 @@ import java.lang.reflect.Type;
|
||||
*/
|
||||
public interface ResourceTypeLoader {
|
||||
|
||||
/**
|
||||
* 自定义的对象注入, 实现需要兼容Field为null的情况
|
||||
*
|
||||
* @param factory ResourceFactory
|
||||
* @param srcResourceName 依附对象的资源名
|
||||
* @param srcObj 依附对象
|
||||
* @param resourceName 资源名
|
||||
* @param field 字段对象
|
||||
* @param attachment
|
||||
* @return Object
|
||||
*/
|
||||
public Object load(
|
||||
ResourceFactory factory,
|
||||
String srcResourceName,
|
||||
Object srcObj,
|
||||
@Nullable String srcResourceName,
|
||||
@Nullable Object srcObj,
|
||||
String resourceName,
|
||||
Field field,
|
||||
Object attachment);
|
||||
|
||||
@Nullable Field field,
|
||||
@Nullable Object attachment);
|
||||
/**
|
||||
* 注入加载器对应的类型
|
||||
*
|
||||
* @return 类型
|
||||
*/
|
||||
public Type resourceType();
|
||||
|
||||
// 返回true: 表示调用ResourceLoader之后资源仍不存在,则会在ResourceFactory里注入默认值null。
|
||||
// 返回false: 表示资源不存在下次仍会调用ResourceLoader自行处理。
|
||||
/**
|
||||
* 是否注入默认值null <br>
|
||||
* 返回true: 表示调用ResourceLoader之后资源仍不存在,则会在ResourceFactory里注入默认值null。 <br>
|
||||
* 返回false: 表示资源不存在下次仍会调用{@link org.redkale.inject.ResourceTypeLoader}自行处理。 <br>
|
||||
*
|
||||
* @return 是否注入默认值null
|
||||
*/
|
||||
default boolean autoNone() {
|
||||
return true;
|
||||
}
|
||||
|
||||
78
src/main/java/org/redkale/source/spi/CacheSourceLoader.java
Normal file
78
src/main/java/org/redkale/source/spi/CacheSourceLoader.java
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
package org.redkale.source.spi;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.redkale.annotation.Resource;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.inject.ResourceTypeLoader;
|
||||
import org.redkale.net.Servlet;
|
||||
import org.redkale.net.sncp.Sncp;
|
||||
import org.redkale.service.Service;
|
||||
import org.redkale.source.CacheSource;
|
||||
import org.redkale.util.RedkaleException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
class CacheSourceLoader implements ResourceTypeLoader {
|
||||
|
||||
private final Logger logger = Logger.getLogger(getClass().getSimpleName());
|
||||
|
||||
private final SourceModuleEngine engine;
|
||||
|
||||
public CacheSourceLoader(SourceModuleEngine engine) {
|
||||
this.engine = engine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object load(
|
||||
ResourceFactory rf,
|
||||
String srcResourceName,
|
||||
Object srcObj,
|
||||
String resourceName,
|
||||
Field field,
|
||||
Object attachment) {
|
||||
try {
|
||||
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) {
|
||||
return null; // 远程模式不得注入
|
||||
}
|
||||
if (srcObj instanceof Servlet) {
|
||||
throw new RedkaleException("CacheSource cannot inject in Servlet " + srcObj);
|
||||
}
|
||||
final boolean ws = (srcObj instanceof org.redkale.net.http.WebSocketNodeService);
|
||||
CacheSource source = engine.loadCacheSource(resourceName, ws);
|
||||
if (field != null) {
|
||||
field.set(srcObj, source);
|
||||
Resource res = field.getAnnotation(Resource.class);
|
||||
if (res != null && res.required() && source == null) {
|
||||
throw new RedkaleException("CacheSource (resourceName = '" + resourceName + "') not found");
|
||||
} else {
|
||||
logger.info("Load CacheSource (type = "
|
||||
+ (source == null ? null : source.getClass().getSimpleName()) + ", resourceName = '"
|
||||
+ resourceName + "')");
|
||||
}
|
||||
}
|
||||
return source;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "DataSource inject error", e);
|
||||
throw e instanceof RuntimeException ? (RuntimeException) e : new RedkaleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type resourceType() {
|
||||
return CacheSource.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean autoNone() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
59
src/main/java/org/redkale/source/spi/DataSourceLoader.java
Normal file
59
src/main/java/org/redkale/source/spi/DataSourceLoader.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
package org.redkale.source.spi;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.inject.ResourceTypeLoader;
|
||||
import org.redkale.net.sncp.Sncp;
|
||||
import org.redkale.service.Service;
|
||||
import org.redkale.source.DataSource;
|
||||
import org.redkale.util.RedkaleException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
class DataSourceLoader implements ResourceTypeLoader {
|
||||
|
||||
private final Logger logger = Logger.getLogger(getClass().getSimpleName());
|
||||
|
||||
private final SourceModuleEngine engine;
|
||||
|
||||
public DataSourceLoader(SourceModuleEngine engine) {
|
||||
this.engine = engine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object load(
|
||||
ResourceFactory rf,
|
||||
String srcResourceName,
|
||||
Object srcObj,
|
||||
String resourceName,
|
||||
Field field,
|
||||
Object attachment) {
|
||||
try {
|
||||
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) {
|
||||
return null; // 远程模式不得注入
|
||||
}
|
||||
DataSource source = engine.loadDataSource(resourceName, false);
|
||||
if (field != null) {
|
||||
field.set(srcObj, source);
|
||||
}
|
||||
return source;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "DataSource inject to " + srcObj + " error", e);
|
||||
throw e instanceof RuntimeException ? (RuntimeException) e : new RedkaleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type resourceType() {
|
||||
return DataSource.class;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
package org.redkale.source.spi;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.inject.ResourceTypeLoader;
|
||||
import org.redkale.net.sncp.Sncp;
|
||||
import org.redkale.service.Service;
|
||||
import org.redkale.source.DataSource;
|
||||
import org.redkale.source.DataSqlMapper;
|
||||
import org.redkale.source.DataSqlSource;
|
||||
import org.redkale.util.RedkaleException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
class DataSqlMapperLoader implements ResourceTypeLoader {
|
||||
|
||||
private final Logger logger = Logger.getLogger(getClass().getSimpleName());
|
||||
|
||||
private final SourceModuleEngine engine;
|
||||
|
||||
public DataSqlMapperLoader(SourceModuleEngine engine) {
|
||||
this.engine = engine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object load(
|
||||
ResourceFactory rf,
|
||||
String srcResourceName,
|
||||
Object srcObj,
|
||||
String resourceName,
|
||||
Field field,
|
||||
Object attachment) {
|
||||
try {
|
||||
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) {
|
||||
return null; // 远程模式不得注入
|
||||
}
|
||||
ResourceFactory resourceFactory = engine.getResourceFactory();
|
||||
Class<? extends DataSqlMapper> mapperType = (Class) field.getType();
|
||||
DataSqlMapper old = resourceFactory.find(resourceName, mapperType);
|
||||
if (old != null) {
|
||||
return old;
|
||||
}
|
||||
DataSource source = engine.loadDataSource(resourceName, false);
|
||||
DataSqlMapper mapper =
|
||||
DataSqlMapperBuilder.createMapper(engine.nativeSqlParser, (DataSqlSource) source, mapperType);
|
||||
resourceFactory.register(resourceName, mapperType, mapper);
|
||||
if (field != null) {
|
||||
field.set(srcObj, mapper);
|
||||
}
|
||||
return mapper;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, DataSqlMapper.class.getSimpleName() + " inject to " + srcObj + " error", e);
|
||||
throw e instanceof RuntimeException ? (RuntimeException) e : new RedkaleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type resourceType() {
|
||||
return DataSqlMapper.class;
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,6 @@
|
||||
*/
|
||||
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;
|
||||
@@ -19,14 +17,10 @@ import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.logging.Level;
|
||||
import org.redkale.annotation.Resource;
|
||||
import org.redkale.boot.Application;
|
||||
import org.redkale.boot.ModuleEngine;
|
||||
import org.redkale.inject.Resourcable;
|
||||
import org.redkale.inject.ResourceEvent;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.inject.ResourceTypeLoader;
|
||||
import org.redkale.net.Servlet;
|
||||
import org.redkale.net.sncp.Sncp;
|
||||
import org.redkale.service.Service;
|
||||
import org.redkale.source.AbstractCacheSource;
|
||||
@@ -38,7 +32,6 @@ import org.redkale.source.DataMemorySource;
|
||||
import org.redkale.source.DataNativeSqlParser;
|
||||
import org.redkale.source.DataSource;
|
||||
import org.redkale.source.DataSources;
|
||||
import org.redkale.source.DataSqlMapper;
|
||||
import org.redkale.source.DataSqlSource;
|
||||
import org.redkale.source.SearchSource;
|
||||
import org.redkale.source.SourceManager;
|
||||
@@ -46,7 +39,6 @@ import org.redkale.util.AnyValue;
|
||||
import org.redkale.util.AnyValueWriter;
|
||||
import org.redkale.util.InstanceProvider;
|
||||
import org.redkale.util.RedkaleClassLoader;
|
||||
import org.redkale.util.RedkaleException;
|
||||
import org.redkale.util.Utility;
|
||||
|
||||
/** @author zhangjx */
|
||||
@@ -135,9 +127,9 @@ public class SourceModuleEngine extends ModuleEngine implements SourceManager {
|
||||
}
|
||||
resourceFactory.register(SourceManager.class, this);
|
||||
// --------------------------------- 注册 DataSource、CacheSource ---------------------------------
|
||||
resourceFactory.register(new DataSourceLoader());
|
||||
resourceFactory.register(new CacheSourceLoader());
|
||||
resourceFactory.register(new DataSqlMapperLoader());
|
||||
resourceFactory.register(new DataSourceLoader(this));
|
||||
resourceFactory.register(new CacheSourceLoader(this));
|
||||
resourceFactory.register(new DataSqlMapperLoader(this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -545,115 +537,4 @@ public class SourceModuleEngine extends ModuleEngine implements SourceManager {
|
||||
return conf;
|
||||
}
|
||||
|
||||
private class DataSqlMapperLoader implements ResourceTypeLoader {
|
||||
|
||||
@Override
|
||||
public Object load(
|
||||
ResourceFactory rf,
|
||||
String srcResourceName,
|
||||
Object srcObj,
|
||||
String resourceName,
|
||||
Field field,
|
||||
Object attachment) {
|
||||
try {
|
||||
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) {
|
||||
return null; // 远程模式不得注入
|
||||
}
|
||||
Class<? extends DataSqlMapper> mapperType = (Class) field.getType();
|
||||
DataSqlMapper old = resourceFactory.find(resourceName, mapperType);
|
||||
if (old != null) {
|
||||
return old;
|
||||
}
|
||||
DataSource source = loadDataSource(resourceName, false);
|
||||
DataSqlMapper mapper =
|
||||
DataSqlMapperBuilder.createMapper(nativeSqlParser, (DataSqlSource) source, mapperType);
|
||||
resourceFactory.register(resourceName, mapperType, mapper);
|
||||
field.set(srcObj, mapper);
|
||||
return mapper;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, DataSqlMapper.class.getSimpleName() + " inject to " + srcObj + " error", e);
|
||||
throw e instanceof RuntimeException ? (RuntimeException) e : new RedkaleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type resourceType() {
|
||||
return DataSqlMapper.class;
|
||||
}
|
||||
}
|
||||
|
||||
private class DataSourceLoader implements ResourceTypeLoader {
|
||||
|
||||
@Override
|
||||
public Object load(
|
||||
ResourceFactory rf,
|
||||
String srcResourceName,
|
||||
Object srcObj,
|
||||
String resourceName,
|
||||
Field field,
|
||||
Object attachment) {
|
||||
try {
|
||||
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) {
|
||||
return null; // 远程模式不得注入
|
||||
}
|
||||
DataSource source = loadDataSource(resourceName, false);
|
||||
field.set(srcObj, source);
|
||||
return source;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "DataSource inject to " + srcObj + " error", e);
|
||||
throw e instanceof RuntimeException ? (RuntimeException) e : new RedkaleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type resourceType() {
|
||||
return DataSource.class;
|
||||
}
|
||||
}
|
||||
|
||||
private class CacheSourceLoader implements ResourceTypeLoader {
|
||||
|
||||
@Override
|
||||
public Object load(
|
||||
ResourceFactory rf,
|
||||
String srcResourceName,
|
||||
Object srcObj,
|
||||
String resourceName,
|
||||
Field field,
|
||||
Object attachment) {
|
||||
try {
|
||||
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) {
|
||||
return null; // 远程模式不得注入
|
||||
}
|
||||
if (srcObj instanceof Servlet) {
|
||||
throw new RedkaleException("CacheSource cannot inject in Servlet " + srcObj);
|
||||
}
|
||||
final boolean ws = (srcObj instanceof org.redkale.net.http.WebSocketNodeService);
|
||||
CacheSource source = loadCacheSource(resourceName, ws);
|
||||
field.set(srcObj, source);
|
||||
Resource res = field.getAnnotation(Resource.class);
|
||||
if (res != null && res.required() && source == null) {
|
||||
throw new RedkaleException("CacheSource (resourceName = '" + resourceName + "') not found");
|
||||
} else {
|
||||
logger.info("Load CacheSource (type = "
|
||||
+ (source == null ? null : source.getClass().getSimpleName()) + ", resourceName = '"
|
||||
+ resourceName + "')");
|
||||
}
|
||||
return source;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "DataSource inject error", e);
|
||||
throw e instanceof RuntimeException ? (RuntimeException) e : new RedkaleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type resourceType() {
|
||||
return CacheSource.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean autoNone() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user