调整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,
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;

View File

@@ -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表示模块不识别此配置项
*

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

View File

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

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) {
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生成器

View File

@@ -233,6 +233,7 @@ public class CachedAsmMethodBoost extends AsmMethodBoost {
}
}
}
actionMap.forEach((field, action) -> {
try {
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);
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());
}

View File

@@ -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();

View File

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

View File

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

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