调整ResourceTypeLoader

This commit is contained in:
redkale
2024-06-11 12:05:37 +08:00
parent b89bc452e6
commit 5913c515b9
19 changed files with 983 additions and 661 deletions

View File

@@ -391,7 +391,9 @@ public final class Application {
Field field, Field field,
Object attachment) { Object attachment) {
try { try {
if (field != null) {
field.set(srcObj, application); field.set(srcObj, application);
}
return application; return application;
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "Resource inject error", e); logger.log(Level.SEVERE, "Resource inject error", e);
@@ -423,7 +425,9 @@ public final class Application {
boolean serv = boolean serv =
RESNAME_SERVER_RESFACTORY.equals(resourceName) || resourceName.equalsIgnoreCase("server"); RESNAME_SERVER_RESFACTORY.equals(resourceName) || resourceName.equalsIgnoreCase("server");
ResourceFactory rs = serv ? rf : (resourceName.isEmpty() ? application.resourceFactory : null); ResourceFactory rs = serv ? rf : (resourceName.isEmpty() ? application.resourceFactory : null);
if (field != null) {
field.set(srcObj, rs); field.set(srcObj, rs);
}
return rs; return rs;
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "Resource inject error", e); logger.log(Level.SEVERE, "Resource inject error", e);
@@ -462,7 +466,9 @@ public final class Application {
break; break;
} }
} }
if (field != null) {
field.set(srcObj, server); field.set(srcObj, server);
}
return server; return server;
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "Resource inject error", e); logger.log(Level.SEVERE, "Resource inject error", e);
@@ -501,7 +507,9 @@ public final class Application {
break; break;
} }
} }
if (field != null) {
field.set(srcObj, server); field.set(srcObj, server);
}
return server; return server;
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "Resource inject error", e); logger.log(Level.SEVERE, "Resource inject error", e);
@@ -540,7 +548,9 @@ public final class Application {
break; break;
} }
} }
if (field != null) {
field.set(srcObj, server); field.set(srcObj, server);
}
return server; return server;
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "Resource inject error", e); logger.log(Level.SEVERE, "Resource inject error", e);
@@ -578,7 +588,9 @@ public final class Application {
builder.version(HttpClient.Version.HTTP_2); builder.version(HttpClient.Version.HTTP_2);
} }
java.net.http.HttpClient httpClient = builder.build(); java.net.http.HttpClient httpClient = builder.build();
if (field != null) {
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; return httpClient;
@@ -606,7 +618,9 @@ public final class Application {
Object attachment) { Object attachment) {
try { try {
WebClient httpClient = WebClient.create(workExecutor, clientAsyncGroup); WebClient httpClient = WebClient.create(workExecutor, clientAsyncGroup);
if (field != null) {
field.set(srcObj, httpClient); field.set(srcObj, httpClient);
}
rf.inject(resourceName, httpClient, null); // 给其可能包含@Resource的字段赋值; rf.inject(resourceName, httpClient, null); // 给其可能包含@Resource的字段赋值;
rf.register(resourceName, WebClient.class, httpClient); rf.register(resourceName, WebClient.class, httpClient);
return httpClient; return httpClient;
@@ -640,7 +654,9 @@ public final class Application {
|| !Objects.equals(clusterAgent.getName(), resourceName) || !Objects.equals(clusterAgent.getName(), resourceName)
|| messageAgent.isRpcFirst()) { || messageAgent.isRpcFirst()) {
HttpRpcClient rpcClient = messageAgent.getHttpRpcClient(); HttpRpcClient rpcClient = messageAgent.getHttpRpcClient();
if (field != null) {
field.set(srcObj, rpcClient); field.set(srcObj, rpcClient);
}
rf.inject(resourceName, rpcClient, null); // 给其可能包含@Resource的字段赋值; rf.inject(resourceName, rpcClient, null); // 给其可能包含@Resource的字段赋值;
rf.register(resourceName, HttpRpcClient.class, rpcClient); rf.register(resourceName, HttpRpcClient.class, rpcClient);
return rpcClient; return rpcClient;
@@ -648,13 +664,17 @@ public final class Application {
} }
if (clusterAgent == null) { if (clusterAgent == null) {
HttpRpcClient rpcClient = new HttpLocalRpcClient(application, resourceName); HttpRpcClient rpcClient = new HttpLocalRpcClient(application, resourceName);
if (field != null) {
field.set(srcObj, rpcClient); field.set(srcObj, rpcClient);
}
rf.inject(resourceName, rpcClient, null); // 给其可能包含@Resource的字段赋值; rf.inject(resourceName, rpcClient, null); // 给其可能包含@Resource的字段赋值;
rf.register(resourceName, HttpRpcClient.class, rpcClient); rf.register(resourceName, HttpRpcClient.class, rpcClient);
return rpcClient; return rpcClient;
} }
HttpRpcClient rpcClient = new HttpClusterRpcClient(application, resourceName, clusterAgent); HttpRpcClient rpcClient = new HttpClusterRpcClient(application, resourceName, clusterAgent);
if (field != null) {
field.set(srcObj, rpcClient); field.set(srcObj, rpcClient);
}
rf.inject(resourceName, rpcClient, null); // 给其可能包含@Resource的字段赋值; rf.inject(resourceName, rpcClient, null); // 给其可能包含@Resource的字段赋值;
rf.register(resourceName, HttpRpcClient.class, rpcClient); rf.register(resourceName, HttpRpcClient.class, rpcClient);
return rpcClient; return rpcClient;

View File

@@ -38,6 +38,18 @@ public abstract class ModuleEngine {
this.environment = Objects.requireNonNull(application.getEnvironment()); 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表示模块不识别此配置项 * 判断模块的配置项合并策略, 返回null表示模块不识别此配置项
* *

View 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;
}
}

View 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;
}
}

View File

@@ -5,8 +5,6 @@
*/ */
package org.redkale.boot; package org.redkale.boot;
import static org.redkale.boot.Application.RESNAME_SNCP_ADDRESS;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.net.*; import java.net.*;
@@ -16,11 +14,8 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.redkale.annotation.*; import org.redkale.annotation.*;
import org.redkale.asm.AsmMethodBoost;
import org.redkale.boot.ClassFilter.FilterEntry; import org.redkale.boot.ClassFilter.FilterEntry;
import org.redkale.cluster.spi.ClusterAgent; 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.mq.spi.MessageAgent;
import org.redkale.net.*; import org.redkale.net.*;
import org.redkale.net.http.*; import org.redkale.net.http.*;
@@ -124,7 +119,7 @@ public class NodeHttpServer extends NodeServer {
@Override @Override
protected void loadService(ClassFilter<? extends Service> serviceFilter) throws Exception { protected void loadService(ClassFilter<? extends Service> serviceFilter) throws Exception {
super.loadService(serviceFilter); super.loadService(serviceFilter);
initWebSocketService(); resourceFactory.register(new NodeWebSocketNodeLoader(this));
} }
@Override @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") @SuppressWarnings("unchecked")
protected void loadHttpFilter(final ClassFilter<? extends Filter> classFilter) throws Exception { protected void loadHttpFilter(final ClassFilter<? extends Filter> classFilter) throws Exception {
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null; final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;

View File

@@ -5,8 +5,6 @@
*/ */
package org.redkale.boot; package org.redkale.boot;
import static org.redkale.boot.Application.*;
import java.io.*; import java.io.*;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.*; import java.lang.reflect.*;
@@ -18,19 +16,15 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.*; import java.util.logging.*;
import org.redkale.annotation.*; import org.redkale.annotation.*;
import org.redkale.annotation.AutoLoad;
import org.redkale.annotation.Command; 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.boot.ClassFilter.FilterEntry;
import org.redkale.cluster.spi.ClusterAgent; import org.redkale.cluster.spi.ClusterAgent;
import org.redkale.inject.ResourceFactory; import org.redkale.inject.ResourceFactory;
import org.redkale.inject.ResourceTypeLoader;
import org.redkale.mq.spi.MessageAgent; import org.redkale.mq.spi.MessageAgent;
import org.redkale.net.*; import org.redkale.net.*;
import org.redkale.net.Filter; import org.redkale.net.Filter;
import org.redkale.net.client.ClientAddress; 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.net.sncp.*;
import org.redkale.service.*; import org.redkale.service.*;
import org.redkale.source.*; import org.redkale.source.*;
@@ -202,7 +196,12 @@ public abstract class NodeServer {
1000); 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", ""); String interceptorClass = this.serverConf.getValue("interceptor", "");
if (!interceptorClass.isEmpty()) { if (!interceptorClass.isEmpty()) {
Class clazz = serverClassLoader.loadClass(interceptorClass); Class clazz = serverClassLoader.loadClass(interceptorClass);
@@ -265,305 +264,6 @@ public abstract class NodeServer {
protected abstract void loadServlet(ClassFilter<? extends Servlet> servletFilter) throws Exception; 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") @SuppressWarnings("unchecked")
protected void loadService(ClassFilter<? extends Service> serviceFilter) throws Exception { protected void loadService(ClassFilter<? extends Service> serviceFilter) throws Exception {
Objects.requireNonNull(serviceFilter); Objects.requireNonNull(serviceFilter);
@@ -618,12 +318,12 @@ public abstract class NodeServer {
if (entry.isExpect()) { if (entry.isExpect()) {
Class t = ResourceFactory.getResourceType(entry.getType()); Class t = ResourceFactory.getResourceType(entry.getType());
if (resourceFactory.findResourceTypeLoader(t) == null) { if (resourceFactory.findResourceTypeLoader(t) == null) {
resourceFactory.register(new ExpectServiceLoader( resourceFactory.register(new NodeExpectServiceLoader(
t, serviceImplClass, serviceCount, rpcGroups, entry, group, localMode)); this, t, serviceImplClass, serviceCount, rpcGroups, entry, group, localMode));
} }
} else { } else {
ExpectServiceLoader resourceLoader = new ExpectServiceLoader( NodeExpectServiceLoader resourceLoader = new NodeExpectServiceLoader(
serviceImplClass, serviceImplClass, serviceCount, rpcGroups, entry, group, localMode); this, serviceImplClass, serviceImplClass, serviceCount, rpcGroups, entry, group, localMode);
resourceLoader.load(resourceFactory, null, null, entry.getName(), null, false); resourceLoader.load(resourceFactory, null, null, entry.getName(), null, false);
} }
} }

View 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;
}
}

View File

@@ -92,7 +92,7 @@ public class CachedAction {
} }
void init(ResourceFactory resourceFactory, Object service) { 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()); String key = environment.getPropertyValue(cached.getKey());
this.templetKey = key; this.templetKey = key;
if (key.startsWith("@")) { // 动态加载缓存key生成器 if (key.startsWith("@")) { // 动态加载缓存key生成器

View File

@@ -233,6 +233,7 @@ public class CachedAsmMethodBoost extends AsmMethodBoost {
} }
} }
} }
actionMap.forEach((field, action) -> { actionMap.forEach((field, action) -> {
try { try {
resourceFactory.inject(action); resourceFactory.inject(action);

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -117,16 +117,16 @@ public class CachedManagerService implements CachedManager, Service {
this.schema = conf.getValue("schema", DEFAULT_SCHEMA); this.schema = conf.getValue("schema", DEFAULT_SCHEMA);
if (this.enabled) { if (this.enabled) {
this.localSource.init(conf); this.localSource.init(conf);
String remoteSourceName = conf.getValue("remote"); String remoteSourceName = conf.getValue("remote", "");
if (remoteSource == null && remoteSourceName != null) { if (remoteSource == null && remoteSourceName != null) {
this.broadcastable = conf.getBoolValue("broadcastable", true);
CacheSource source = application.loadCacheSource(remoteSourceName, false); CacheSource source = application.loadCacheSource(remoteSourceName, false);
if (source == null) { if (source == null && !remoteSourceName.isEmpty()) {
throw new RedkaleException("Not found CacheSource '" + remoteSourceName + "'"); throw new RedkaleException("Not found CacheSource '" + remoteSourceName + "'");
} }
this.remoteSource = source; this.remoteSource = source;
this.broadcastable = conf.getBoolValue("broadcastable", true);
} }
if (remoteSource != null) { if (remoteSource != null && this.broadcastable) {
this.remoteListener = new CacheRemoteListener(); this.remoteListener = new CacheRemoteListener();
this.remoteSource.subscribe(CachedEventMessage.class, remoteListener, getChannelTopic()); this.remoteSource.subscribe(CachedEventMessage.class, remoteListener, getChannelTopic());
} }

View File

@@ -3,26 +3,19 @@
*/ */
package org.redkale.cached.spi; package org.redkale.cached.spi;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import org.redkale.asm.AsmMethodBoost; import org.redkale.asm.AsmMethodBoost;
import org.redkale.boot.Application; import org.redkale.boot.Application;
import org.redkale.boot.ModuleEngine; import org.redkale.boot.ModuleEngine;
import org.redkale.cached.CachedManager; import org.redkale.cached.CachedManager;
import org.redkale.inject.ResourceFactory;
import org.redkale.inject.ResourceTypeLoader;
import org.redkale.service.Service; import org.redkale.service.Service;
import org.redkale.util.AnyValue; import org.redkale.util.AnyValue;
import org.redkale.util.AnyValueWriter;
import org.redkale.util.InstanceProvider; import org.redkale.util.InstanceProvider;
import org.redkale.util.RedkaleClassLoader; import org.redkale.util.RedkaleClassLoader;
import org.redkale.util.RedkaleException; import org.redkale.util.RedkaleException;
@@ -40,7 +33,7 @@ public class CachedModuleEngine extends ModuleEngine {
protected static final String CONFIG_NAME = "cached"; 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) { public CachedModuleEngine(Application application) {
super(application); super(application);
@@ -81,7 +74,7 @@ public class CachedModuleEngine extends ModuleEngine {
// 设置缓存管理器 // 设置缓存管理器
AnyValue[] configs = application.getAppConfig().getAnyValues(CONFIG_NAME); AnyValue[] configs = application.getAppConfig().getAnyValues(CONFIG_NAME);
if (configs == null || configs.length == 0) { if (configs == null || configs.length == 0) {
configs = new AnyValue[] {new AnyValueWriter()}; configs = new AnyValue[] {AnyValue.create()};
} }
Map<String, AnyValue> configMap = new HashMap<>(); Map<String, AnyValue> configMap = new HashMap<>();
for (AnyValue config : configs) { for (AnyValue config : configs) {
@@ -92,94 +85,8 @@ public class CachedModuleEngine extends ModuleEngine {
} }
configMap.put(name, config); configMap.put(name, config);
} }
this.resourceFactory.register(new ResourceTypeLoader() { this.resourceFactory.register(new CachedManagerLoader(this, configMap));
this.resourceFactory.register(new CachedKeyGeneratorLoader(this));
@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;
}
});
} }
/** /**
@@ -198,7 +105,7 @@ public class CachedModuleEngine extends ModuleEngine {
} }
} }
private CachedManager createManager(AnyValue conf) { protected CachedManager createManager(AnyValue conf) {
Iterator<CachedManagerProvider> it = ServiceLoader.load( Iterator<CachedManagerProvider> it = ServiceLoader.load(
CachedManagerProvider.class, application.getClassLoader()) CachedManagerProvider.class, application.getClassLoader())
.iterator(); .iterator();

View File

@@ -686,6 +686,32 @@ public final class ResourceFactory {
return null; 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) { public <A> List<A> query(Class<? extends A> clazz) {
return query(new ArrayList<>(), clazz); return query(new ArrayList<>(), clazz);
} }
@@ -1097,7 +1123,7 @@ public final class ResourceFactory {
return parent == null ? null : parent.findResourceTypeLoader(clazz); 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); ResourceTypeLoader it = this.findMatchTypeLoader(ft, field);
return it == null ? findRegxTypeLoader(ft, field) : it; return it == null ? findRegxTypeLoader(ft, field) : it;
} }
@@ -1109,7 +1135,7 @@ public final class ResourceFactory {
return parent.parentRoot(); return parent.parentRoot();
} }
private ResourceTypeLoader findMatchTypeLoader(Type ft, Field field) { private ResourceTypeLoader findMatchTypeLoader(Type ft, @Nullable Field field) {
ResourceTypeLoader it = this.resTypeLoaderMap.get(ft); ResourceTypeLoader it = this.resTypeLoaderMap.get(ft);
if (it == null && field != null) { if (it == null && field != null) {
it = this.resTypeLoaderMap.get(field.getType()); it = this.resTypeLoaderMap.get(field.getType());
@@ -1120,7 +1146,7 @@ public final class ResourceFactory {
return parent == null ? null : parent.findMatchTypeLoader(ft, field); 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) { if (field == null) {
return null; return null;
} }

View File

@@ -4,6 +4,7 @@ package org.redkale.inject;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import org.redkale.annotation.Nullable;
/** /**
* 自定义注入加载器 * 自定义注入加载器
@@ -14,18 +15,38 @@ import java.lang.reflect.Type;
*/ */
public interface ResourceTypeLoader { public interface ResourceTypeLoader {
/**
* 自定义的对象注入, 实现需要兼容Field为null的情况
*
* @param factory ResourceFactory
* @param srcResourceName 依附对象的资源名
* @param srcObj 依附对象
* @param resourceName 资源名
* @param field 字段对象
* @param attachment
* @return Object
*/
public Object load( public Object load(
ResourceFactory factory, ResourceFactory factory,
String srcResourceName, @Nullable String srcResourceName,
Object srcObj, @Nullable Object srcObj,
String resourceName, String resourceName,
Field field, @Nullable Field field,
Object attachment); @Nullable Object attachment);
/**
* 注入加载器对应的类型
*
* @return 类型
*/
public Type resourceType(); 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() { default boolean autoNone() {
return true; return true;
} }

View 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;
}
}

View 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;
}
}

View File

@@ -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;
}
}

View File

@@ -3,8 +3,6 @@
*/ */
package org.redkale.source.spi; package org.redkale.source.spi;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@@ -19,14 +17,10 @@ import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level; import java.util.logging.Level;
import org.redkale.annotation.Resource;
import org.redkale.boot.Application; import org.redkale.boot.Application;
import org.redkale.boot.ModuleEngine; import org.redkale.boot.ModuleEngine;
import org.redkale.inject.Resourcable; import org.redkale.inject.Resourcable;
import org.redkale.inject.ResourceEvent; 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.net.sncp.Sncp;
import org.redkale.service.Service; import org.redkale.service.Service;
import org.redkale.source.AbstractCacheSource; import org.redkale.source.AbstractCacheSource;
@@ -38,7 +32,6 @@ import org.redkale.source.DataMemorySource;
import org.redkale.source.DataNativeSqlParser; import org.redkale.source.DataNativeSqlParser;
import org.redkale.source.DataSource; import org.redkale.source.DataSource;
import org.redkale.source.DataSources; import org.redkale.source.DataSources;
import org.redkale.source.DataSqlMapper;
import org.redkale.source.DataSqlSource; import org.redkale.source.DataSqlSource;
import org.redkale.source.SearchSource; import org.redkale.source.SearchSource;
import org.redkale.source.SourceManager; import org.redkale.source.SourceManager;
@@ -46,7 +39,6 @@ import org.redkale.util.AnyValue;
import org.redkale.util.AnyValueWriter; import org.redkale.util.AnyValueWriter;
import org.redkale.util.InstanceProvider; import org.redkale.util.InstanceProvider;
import org.redkale.util.RedkaleClassLoader; import org.redkale.util.RedkaleClassLoader;
import org.redkale.util.RedkaleException;
import org.redkale.util.Utility; import org.redkale.util.Utility;
/** @author zhangjx */ /** @author zhangjx */
@@ -135,9 +127,9 @@ public class SourceModuleEngine extends ModuleEngine implements SourceManager {
} }
resourceFactory.register(SourceManager.class, this); resourceFactory.register(SourceManager.class, this);
// --------------------------------- 注册 DataSource、CacheSource --------------------------------- // --------------------------------- 注册 DataSource、CacheSource ---------------------------------
resourceFactory.register(new DataSourceLoader()); resourceFactory.register(new DataSourceLoader(this));
resourceFactory.register(new CacheSourceLoader()); resourceFactory.register(new CacheSourceLoader(this));
resourceFactory.register(new DataSqlMapperLoader()); resourceFactory.register(new DataSqlMapperLoader(this));
} }
/** /**
@@ -545,115 +537,4 @@ public class SourceModuleEngine extends ModuleEngine implements SourceManager {
return conf; 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;
}
}
} }