use of org.redkale.boot.Application in project redkale by redkale.
the class NodeServer method initResource.
private void initResource() {
final NodeServer self = this;
// ---------------------------------------------------------------------------------------------
final ResourceFactory appResFactory = application.getResourceFactory();
final TransportFactory appSncpTranFactory = application.getSncpTransportFactory();
final AnyValue resources = application.config.getAnyValue("resources");
final String confURI = appResFactory.find(RESNAME_APP_CONF, String.class);
final Map<String, SimpleEntry<Class, AnyValue>> cacheResource = new HashMap<>();
final Map<String, SimpleEntry<Class, AnyValue>> dataResources = new HashMap<>();
if (resources != null) {
for (AnyValue sourceConf : resources.getAnyValues("source")) {
try {
String classval = sourceConf.getValue("value");
Class type = null;
if (classval == null || classval.isEmpty()) {
RedkaleClassLoader.putServiceLoader(CacheSourceProvider.class);
List<CacheSourceProvider> providers = new ArrayList<>();
Iterator<CacheSourceProvider> it = ServiceLoader.load(CacheSourceProvider.class, serverClassLoader).iterator();
while (it.hasNext()) {
CacheSourceProvider s = it.next();
if (s != null)
RedkaleClassLoader.putReflectionPublicConstructors(s.getClass(), s.getClass().getName());
if (s != null && s.acceptsConf(sourceConf)) {
providers.add(s);
}
}
Collections.sort(providers, (a, b) -> {
Priority p1 = a == null ? null : a.getClass().getAnnotation(Priority.class);
Priority p2 = b == null ? null : b.getClass().getAnnotation(Priority.class);
return (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value());
});
for (CacheSourceProvider provider : providers) {
type = provider.sourceClass();
if (type != null)
break;
}
} else {
type = serverClassLoader.loadClass(classval);
}
if (type == DataSource.class) {
type = DataMemorySource.class;
for (AnyValue itemConf : sourceConf.getAnyValues("property")) {
if (itemConf.getValue("name", "").contains(DataSources.JDBC_URL)) {
type = DataJdbcSource.class;
break;
}
}
}
if (!Service.class.isAssignableFrom(type)) {
logger.log(Level.SEVERE, "load application source resource, but not Service error: " + sourceConf);
} else if (CacheSource.class.isAssignableFrom(type)) {
cacheResource.put(sourceConf.getValue("name", ""), new SimpleEntry(type, sourceConf));
} else if (DataSource.class.isAssignableFrom(type)) {
dataResources.put(sourceConf.getValue("name", ""), new SimpleEntry(type, sourceConf));
} else {
logger.log(Level.SEVERE, "load application source resource, but not CacheSource error: " + sourceConf);
}
} catch (Exception e) {
logger.log(Level.SEVERE, "load application source resource error: " + sourceConf, e);
}
}
}
// ------------------------------------- 注册 Resource --------------------------------------------------------
resourceFactory.register((ResourceFactory rf, final Object src, String resourceName, Field field, final Object attachment) -> {
try {
Resource res = field.getAnnotation(Resource.class);
if (res == null || !res.name().startsWith("properties."))
return;
// 远程模式不得注入 DataSource
if ((src instanceof Service) && Sncp.isRemote((Service) src))
return;
Class type = field.getType();
if (type != AnyValue.class && type != AnyValue[].class)
return;
Object resource = null;
final AnyValue properties = resources == null ? null : resources.getAnyValue("properties");
if (properties != null && type == AnyValue.class) {
resource = properties.getAnyValue(res.name().substring("properties.".length()));
appResFactory.register(resourceName, AnyValue.class, resource);
} else if (properties != null && type == AnyValue[].class) {
resource = properties.getAnyValues(res.name().substring("properties.".length()));
appResFactory.register(resourceName, AnyValue[].class, resource);
}
field.set(src, resource);
} catch (Exception e) {
logger.log(Level.SEVERE, "Resource inject error", e);
}
}, AnyValue.class, AnyValue[].class);
// ------------------------------------- 注册 Local AutoLoad(false) Service --------------------------------------------------------
resourceFactory.register((ResourceFactory rf, final Object src, String resourceName, Field field, final Object attachment) -> {
Class<Service> resServiceType = Service.class;
try {
if (field.getAnnotation(Resource.class) == null)
return;
// 远程模式不得注入 AutoLoad Service
if ((src instanceof Service) && Sncp.isRemote((Service) src))
return;
if (!Service.class.isAssignableFrom(field.getType()))
return;
resServiceType = (Class) field.getType();
if (resServiceType.getAnnotation(Local.class) == null)
return;
AutoLoad al = resServiceType.getAnnotation(AutoLoad.class);
if (al == null || al.value())
return;
// ResourceFactory resfactory = (isSNCP() ? appResFactory : resourceFactory);
SncpClient client = src instanceof Service ? Sncp.getSncpClient((Service) src) : null;
final InetSocketAddress sncpAddr = client == null ? null : client.getClientAddress();
final Set<String> groups = new HashSet<>();
Service service = Modifier.isFinal(resServiceType.getModifiers()) ? (Service) resServiceType.getConstructor().newInstance() : Sncp.createLocalService(serverClassLoader, resourceName, resServiceType, null, appResFactory, appSncpTranFactory, sncpAddr, groups, null);
appResFactory.register(resourceName, resServiceType, service);
field.set(src, service);
// 给其可能包含@Resource的字段赋值;
rf.inject(service, self);
if (!application.isCompileMode())
service.init(null);
logger.info("[" + Thread.currentThread().getName() + "] Load Service(@Local @AutoLoad service = " + resServiceType.getSimpleName() + ", resourceName = '" + resourceName + "')");
} catch (Exception e) {
logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] Load @Local @AutoLoad(false) Service inject " + resServiceType + " to " + src + " error", e);
}
}, Service.class);
// ------------------------------------- 注册 DataSource --------------------------------------------------------
resourceFactory.register((ResourceFactory rf, final Object src, String resourceName, Field field, final Object attachment) -> {
try {
if (field.getAnnotation(Resource.class) == null)
return;
// 远程模式不得注入 DataSource
if ((src instanceof Service) && Sncp.isRemote((Service) src))
return;
SimpleEntry<Class, AnyValue> resEntry = dataResources.get(resourceName);
AnyValue sourceConf = resEntry == null ? null : resEntry.getValue();
DataSource source = null;
if (sourceConf != null) {
final Class sourceType = resEntry.getKey();
if (sourceType == DataJdbcSource.class) {
source = DataSources.createDataSource(resourceName, sourceConf);
} else {
boolean can = false;
RedkaleClassLoader.putReflectionPublicConstructors(sourceType, sourceType.getName());
for (Constructor cr : sourceType.getConstructors()) {
if (cr.getParameterCount() == 0) {
can = true;
break;
}
}
if (DataSource.class.isAssignableFrom(sourceType) && can) {
// 必须有空构造函数
if (Modifier.isFinal(sourceType.getModifiers()) || sourceType.getAnnotation(Local.class) != null) {
source = (DataSource) sourceType.getConstructor().newInstance();
RedkaleClassLoader.putReflectionPublicConstructors(sourceType, sourceType.getName());
} else {
final Service srcService = (Service) src;
SncpClient client = Sncp.getSncpClient(srcService);
final InetSocketAddress sncpAddr = client == null ? null : client.getClientAddress();
final Set<String> groups = new HashSet<>();
source = (DataSource) Sncp.createLocalService(serverClassLoader, resourceName, sourceType, client == null ? null : client.getMessageAgent(), appResFactory, appSncpTranFactory, sncpAddr, groups, Sncp.getConf(srcService));
}
}
}
}
if (source == null) {
// 从persistence.xml配置中创建
source = DataSources.createDataSource(confURI, resourceName);
}
RedkaleClassLoader.putReflectionPublicConstructors(source.getClass(), source.getClass().getName());
application.dataSources.add(source);
ResourceType rt = source.getClass().getAnnotation(ResourceType.class);
if (rt != null && rt.value() != DataSource.class) {
appResFactory.register(resourceName, rt.value(), source);
} else if (source instanceof SearchSource) {
appResFactory.register(resourceName, SearchSource.class, source);
}
appResFactory.register(resourceName, DataSource.class, source);
field.set(src, source);
// 给AsyncGroup和其他@Resource的字段赋值;
rf.inject(source, self);
// NodeServer.this.watchFactory.inject(src);
if (!application.isCompileMode() && source instanceof Service)
((Service) source).init(sourceConf);
logger.info("[" + Thread.currentThread().getName() + "] Load DataSource (type = " + source.getClass().getSimpleName() + ", resourceName = '" + resourceName + "')");
} catch (Exception e) {
logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] DataSource inject to " + src + " error", e);
}
}, DataSource.class);
// ------------------------------------- 注册 CacheSource --------------------------------------------------------
resourceFactory.register(new ResourceFactory.ResourceLoader() {
@Override
public void load(ResourceFactory rf, final Object src, final String resourceName, Field field, final Object attachment) {
try {
if (field.getAnnotation(Resource.class) == null)
return;
if (!(src instanceof Service))
throw new RuntimeException("CacheSource must be inject in Service, cannot " + src);
// 远程模式不需要注入 CacheSource
if ((src instanceof Service) && Sncp.isRemote((Service) src))
return;
final Service srcService = (Service) src;
SncpClient client = Sncp.getSncpClient(srcService);
final InetSocketAddress sncpAddr = client == null ? null : client.getClientAddress();
SimpleEntry<Class, AnyValue> resEntry = cacheResource.get(resourceName);
AnyValue sourceConf = resEntry == null ? null : resEntry.getValue();
if (sourceConf == null) {
SimpleEntry<Class, AnyValue> resEntry2 = dataResources.get(resourceName);
sourceConf = resEntry2 == null ? null : resEntry2.getValue();
}
Class sourceType0 = CacheMemorySource.class;
if (sourceConf != null) {
String classval = sourceConf.getValue("value");
if (classval == null || classval.isEmpty()) {
RedkaleClassLoader.putServiceLoader(CacheSourceProvider.class);
List<CacheSourceProvider> providers = new ArrayList<>();
Iterator<CacheSourceProvider> it = ServiceLoader.load(CacheSourceProvider.class, serverClassLoader).iterator();
while (it.hasNext()) {
CacheSourceProvider s = it.next();
if (s != null)
RedkaleClassLoader.putReflectionPublicConstructors(s.getClass(), s.getClass().getName());
if (s != null && s.acceptsConf(sourceConf)) {
providers.add(s);
}
}
Collections.sort(providers, (a, b) -> {
Priority p1 = a == null ? null : a.getClass().getAnnotation(Priority.class);
Priority p2 = b == null ? null : b.getClass().getAnnotation(Priority.class);
return (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value());
});
for (CacheSourceProvider provider : providers) {
sourceType0 = provider.sourceClass();
if (sourceType0 != null)
break;
}
} else {
sourceType0 = serverClassLoader.loadClass(classval);
}
}
final Class sourceType = sourceType0;
Object source = null;
if (CacheSource.class.isAssignableFrom(sourceType)) {
// CacheSource
RedkaleClassLoader.putReflectionPublicConstructors(sourceType, sourceType.getName());
source = sourceType == CacheMemorySource.class ? new CacheMemorySource(resourceName) : (Modifier.isFinal(sourceType.getModifiers()) || sourceType.getAnnotation(Local.class) != null) ? sourceType.getConstructor().newInstance() : (CacheSource) Sncp.createLocalService(serverClassLoader, resourceName, sourceType, client == null ? null : client.getMessageAgent(), appResFactory, appSncpTranFactory, sncpAddr, null, Sncp.getConf(srcService));
Type genericType = field.getGenericType();
application.cacheSources.add((CacheSource) source);
appResFactory.register(resourceName, CacheSource.class, source);
if (genericType != CacheSource.class) {
appResFactory.register(resourceName, genericType, source);
}
}
field.set(src, source);
//
rf.inject(source, self);
if (!application.isCompileMode() && source instanceof Service)
((Service) source).init(sourceConf);
if ((src instanceof org.redkale.net.http.WebSocketNodeService) && sncpAddr != null) {
// 只有WebSocketNodeService的服务才需要给SNCP服务注入CacheMemorySource
NodeSncpServer sncpServer = application.findNodeSncpServer(sncpAddr);
if (source != null && source.getClass().getAnnotation(Local.class) == null) {
// 本地模式的Service不生成SncpServlet
sncpServer.getSncpServer().addSncpServlet((Service) source);
}
// logger.info("[" + Thread.currentThread().getName() + "] Load Service " + source);
}
logger.info("[" + Thread.currentThread().getName() + "] Load CacheSource (type = " + source.getClass().getSimpleName() + ", resourceName = '" + resourceName + "')");
} catch (Exception e) {
logger.log(Level.SEVERE, "DataSource inject error", e);
}
}
@Override
public boolean autoNone() {
return false;
}
}, CacheSource.class);
// ------------------------------------- 注册 WebSocketNode --------------------------------------------------------
resourceFactory.register(new ResourceFactory.ResourceLoader() {
@Override
public void load(ResourceFactory rf, final Object src, final String resourceName, Field field, final Object attachment) {
try {
if (field.getAnnotation(Resource.class) == null)
return;
// 远程模式不需要注入 WebSocketNode
if ((src instanceof Service) && Sncp.isRemote((Service) src))
return;
Service nodeService = (Service) 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);
nodeService = Sncp.createLocalService(serverClassLoader, resourceName, org.redkale.net.http.WebSocketNodeService.class, Sncp.getMessageAgent((Service) src), application.getResourceFactory(), application.getSncpTransportFactory(), NodeServer.this.sncpAddress, groups, (AnyValue) null);
(isSNCP() ? appResFactory : resourceFactory).register(resourceName, WebSocketNode.class, nodeService);
((org.redkale.net.http.WebSocketNodeService) nodeService).setName(resourceName);
}
resourceFactory.inject(nodeService, self);
MessageAgent messageAgent = Sncp.getMessageAgent((Service) src);
if (messageAgent != null && Sncp.getMessageAgent(nodeService) == null)
Sncp.setMessageAgent(nodeService, messageAgent);
field.set(src, nodeService);
if (Sncp.isRemote(nodeService)) {
remoteServices.add(nodeService);
} else {
// 动态加载的Service也存在按需加载的注入资源
rf.inject(nodeService);
localServices.add(nodeService);
interceptorServices.add(nodeService);
if (consumer != null)
consumer.accept(null, nodeService);
}
} catch (Exception e) {
logger.log(Level.SEVERE, "WebSocketNode inject error", e);
}
}
@Override
public boolean autoNone() {
return false;
}
}, WebSocketNode.class);
}
Aggregations