BootModule
This commit is contained in:
12
README.md
12
README.md
@@ -1,7 +1,7 @@
|
||||

|
||||
|
||||
## 简介
|
||||
Redkale (中文名: 红菜苔,一种湖北特产蔬菜) 是基于Java 11全新的微服务框架, 包含HTTP、WebSocket、TCP/UDP、数据序列化、数据缓存、依赖注入等功能。 本框架致力于简化集中式和微服务架构的开发,在增强开发敏捷性的同时保持高性能。
|
||||
  Redkale (中文名: 红菜苔,一种湖北特产蔬菜) 是基于Java 11全新的微服务框架, 包含HTTP、WebSocket、TCP/UDP、数据序列化、数据缓存、依赖注入等功能。 本框架致力于简化集中式和微服务架构的开发,在增强开发敏捷性的同时保持高性能。
|
||||
|
||||
主要特点::
|
||||
* 大量使用Java 8+新特性(接口默认值、Stream、Lambda、内置的ASM、HttpClient等)
|
||||
@@ -25,12 +25,12 @@
|
||||
* [FAQ](docs/faq.md)
|
||||
|
||||
## 设计理念
|
||||
作为一个全新的微服务框架,Redkale在接口定义上使用了Java 8以上版本的大量新特性,接口有默认实现、接口带静态方法、重复注解等特性,同时在设计上与主流框架有很大不同。Redkale是按组件形式设计的,而非以容器为主,几乎每个子包都是能提供独立功能的组件。如Tomcat是按容器设计的,所有web资源/配置由Tomcat控制,开发者很能难控制到Tomcat内部,而Redkale的HTTP服务只是个组件,开发者既可以自己启动和配置HttpServer,也可以把Redkale当成容器通过Redkale进程来初始化服务。Spring的Ioc容器也是如此,Redkale提供的依赖注入仅通过ResouceFactory一个类来控制,非常轻量,并且可动态更改已注入的资源。Spring提倡控制反转思想,而自身的容器却让开发者很难控制。Redkale是一个既能以组件形式也能以容器形式存在的框架。从整体上看,Redkale的架构分两层:接口和默认实现。开发者若想替换掉Redkale内置的HTTP服务而使用符合JavaEE规范的HttpServlet, 可以采用自定义协议基于JSR 340(Servlet 3.1)来实现自己的HTTP服务;若想使用Hibernate作为数据库操作,可以写一个自己的DataSource实现类;JSON的序列化和反序列化也可以使用第三方的实现;Memcached或Redis也可以作为另一个CacheSource的实现替换Redkale的默认实现。这其实包含了控制反转的思想,让框架里的各个组件均可让开发者控制。
|
||||
与主流框架比,功能上Redkale显得很简单,这体现了Redkale的简易性,而并非是不足,从一个良好的设计习惯或架构上来看,有些常用功能是不需要提供的,如Redkale的HTTP服务不支持JSP, JSP其实算是一个落后的技术,现在是一个多样化终端的时代,终端不只局限于桌面程序和PC浏览器,还有原生App、混合式App、微信端、移动H5、提供第三方接口等各种形式的终端,这些都不是JSP能方便兼顾的,而HTTP+JSON作为通用性接口可以避免重复开发,模版引擎的功能加上各种强大的JS框架足以取代JSP。Redkale在功能上做了筛选,不会为了迎合主流而提供,而是以良好的设计思想为指导。这是Redkale的主导思维。
|
||||
  作为一个全新的微服务框架,Redkale在接口定义上使用了Java 8以上版本的大量新特性,接口有默认实现、接口带静态方法、重复注解等特性,同时在设计上与主流框架有很大不同。Redkale是按组件形式设计的,而非以容器为主,几乎每个子包都是能提供独立功能的组件。如Tomcat是按容器设计的,所有web资源/配置由Tomcat控制,开发者很能难控制到Tomcat内部,而Redkale的HTTP服务只是个组件,开发者既可以自己启动和配置HttpServer,也可以把Redkale当成容器通过Redkale进程来初始化服务。Spring的Ioc容器也是如此,Redkale提供的依赖注入仅通过ResouceFactory一个类来控制,非常轻量,并且可动态更改已注入的资源。Spring提倡控制反转思想,而自身的容器却让开发者很难控制。Redkale是一个既能以组件形式也能以容器形式存在的框架。从整体上看,Redkale的架构分两层:接口和默认实现。开发者若想替换掉Redkale内置的HTTP服务而使用符合JavaEE规范的HttpServlet, 可以采用自定义协议基于JSR 340(Servlet 3.1)来实现自己的HTTP服务;若想使用Hibernate作为数据库操作,可以写一个自己的DataSource实现类;JSON的序列化和反序列化也可以使用第三方的实现;Memcached或Redis也可以作为另一个CacheSource的实现替换Redkale的默认实现。这其实包含了控制反转的思想,让框架里的各个组件均可让开发者控制。
|
||||
  与主流框架比,功能上Redkale显得很简单,这体现了Redkale的简易性,而并非是不足,从一个良好的设计习惯或架构上来看,有些常用功能是不需要提供的,如Redkale的HTTP服务不支持JSP, JSP其实算是一个落后的技术,现在是一个多样化终端的时代,终端不只局限于桌面程序和PC浏览器,还有原生App、混合式App、微信端、移动H5、提供第三方接口等各种形式的终端,这些都不是JSP能方便兼顾的,而HTTP+JSON作为通用性接口可以避免重复开发,模版引擎的功能加上各种强大的JS框架足以取代JSP。Redkale在功能上做了筛选,不会为了迎合主流而提供,而是以良好的设计思想为指导。这是Redkale的主导思维。
|
||||
|
||||
<b>详情请访问: <a href='https://redkale.org' target='_blank'>https://redkale.org</a></b>
|
||||
   <b>详情请访问:  <a href='https://redkale.org' target='_blank'>https://redkale.org</a></b>
|
||||
|
||||
<b>基本文档: <a href='https://redkale.org/articles.html' target='_blank'>https://redkale.org/articles.html</a></b>
|
||||
   <b>基本文档:  <a href='https://redkale.org/articles.html' target='_blank'>https://redkale.org/articles.html</a></b>
|
||||
|
||||
<b>欢迎加入Redkale QQ群: 527523235</b>
|
||||
   <b>欢迎加入Redkale QQ群: 527523235</b>
|
||||
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
# 创建工程
|
||||
在IDE中使用ant或maven方式创建工程,增加redkale的依赖。下载解压
|
||||
|
||||

|
||||
  
|
||||
|
||||
并覆盖到工程目录下。
|
||||
* bin: 存放启动/关闭脚本(start.sh、shutdown.sh、redkale.sh等)
|
||||
* conf : 存放服务器所需配置文件:
|
||||
* application.xml: 服务配置文件 (必需);
|
||||
* logging.properties:日志配置文件 (可选);
|
||||
* source.properties: 数据库配置文件 (可选);
|
||||
*    application.xml: 服务配置文件 (必需);
|
||||
*    logging.properties:日志配置文件 (可选);
|
||||
*    source.properties: 数据库配置文件 (可选);
|
||||
* lib : 存放服务所依赖jar
|
||||
* logs : logging.properties配置中默认的日志存放目录。
|
||||
|
||||
@@ -55,7 +55,7 @@ public class HelloService implements Service {
|
||||
```
|
||||
运行结果:
|
||||
|
||||

|
||||
  
|
||||
|
||||
# 进一步阅读
|
||||
* 详细的配置说明看[这里](config.md)。
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Service组件
|
||||
>Service是Redkale最核心的组件,主要处理业务逻辑和操作数据层。Service实例分两种模式: <b>本地模式</b>和<b>远程模式</b>。其模式由```conf/application.xml```文件来配置。开发人员在调用过程中通常不需要区分Service实例是哪种模式。 <br/>
|
||||
>并不是Sevice都能进行本地和远程模式切换, 以下情况的Service不能转成远程模式:
|
||||
1、Service类修饰为```final``` <br>
|
||||
2、Service类被标记```@Local``` <br>
|
||||
3、Service类被标记```@Component``` <br>
|
||||
  Service是Redkale最核心的组件,主要处理业务逻辑和操作数据层。Service实例分两种模式: <b>本地模式</b>和<b>远程模式</b>。其模式由```conf/application.xml```文件来配置。开发人员在调用过程中通常不需要区分Service实例是哪种模式。 <br/>
|
||||
  并不是Sevice都能进行本地和远程模式切换, 以下情况的Service不能转成远程模式:
|
||||
     1、Service类修饰为```final``` <br>
|
||||
     2、Service类被标记```@Local``` <br>
|
||||
     3、Service类被标记```@Component``` <br>
|
||||
|
||||
Redkale进程启动时扫描可加载的Service实现类,根据配置文件配置的模式采用```ASM```技术动态生成相应的Service临时类进行实例化,并注册到ResourceFactory同其他Service、Servlet依赖注入。
|
||||
  Redkale进程启动时扫描可加载的Service实现类,根据配置文件配置的模式采用```ASM```技术动态生成相应的Service临时类进行实例化,并注册到ResourceFactory同其他Service、Servlet依赖注入。
|
||||
|
||||
@@ -26,7 +26,9 @@ module org.redkale {
|
||||
exports org.redkale.convert.ext;
|
||||
exports org.redkale.convert.json;
|
||||
exports org.redkale.convert.proto;
|
||||
exports org.redkale.convert.spi;
|
||||
exports org.redkale.inject;
|
||||
exports org.redkale.inject.spi;
|
||||
exports org.redkale.lock;
|
||||
exports org.redkale.lock.spi;
|
||||
exports org.redkale.mq;
|
||||
@@ -36,22 +38,24 @@ module org.redkale {
|
||||
exports org.redkale.net.http;
|
||||
exports org.redkale.net.sncp;
|
||||
exports org.redkale.persistence;
|
||||
exports org.redkale.props.spi;
|
||||
exports org.redkale.schedule;
|
||||
exports org.redkale.schedule.spi;
|
||||
exports org.redkale.service;
|
||||
exports org.redkale.source;
|
||||
exports org.redkale.source.spi;
|
||||
exports org.redkale.util;
|
||||
exports org.redkale.watch;
|
||||
|
||||
uses org.redkale.boot.PropertiesAgentProvider;
|
||||
uses org.redkale.props.spi.PropertiesAgentProvider;
|
||||
uses org.redkale.cache.spi.CacheManagerProvider;
|
||||
uses org.redkale.cluster.spi.ClusterAgentProvider;
|
||||
uses org.redkale.convert.ConvertProvider;
|
||||
uses org.redkale.inject.ResourceAnnotationProvider;
|
||||
uses org.redkale.convert.spi.ConvertProvider;
|
||||
uses org.redkale.inject.spi.ResourceAnnotationProvider;
|
||||
uses org.redkale.mq.spi.MessageAgentProvider;
|
||||
uses org.redkale.schedule.spi.ScheduleManagerProvider;
|
||||
uses org.redkale.source.CacheSourceProvider;
|
||||
uses org.redkale.source.DataSourceProvider;
|
||||
uses org.redkale.source.DataNativeSqlParserProvider;
|
||||
uses org.redkale.source.spi.CacheSourceProvider;
|
||||
uses org.redkale.source.spi.DataSourceProvider;
|
||||
uses org.redkale.source.spi.DataNativeSqlParserProvider;
|
||||
|
||||
}
|
||||
|
||||
@@ -42,9 +42,11 @@ import org.redkale.mq.spi.MessageModuleEngine;
|
||||
import org.redkale.net.*;
|
||||
import org.redkale.net.http.*;
|
||||
import org.redkale.net.sncp.*;
|
||||
import org.redkale.props.spi.PropertiesModule;
|
||||
import org.redkale.schedule.spi.ScheduleModuleEngine;
|
||||
import org.redkale.service.Service;
|
||||
import org.redkale.source.*;
|
||||
import org.redkale.source.spi.SourceModuleEngine;
|
||||
import org.redkale.util.*;
|
||||
import org.redkale.watch.WatchServlet;
|
||||
|
||||
|
||||
55
src/main/java/org/redkale/boot/BootModule.java
Normal file
55
src/main/java/org/redkale/boot/BootModule.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
package org.redkale.boot;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
import org.redkale.inject.ResourceEvent;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.util.Environment;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public abstract class BootModule {
|
||||
|
||||
protected final Application application;
|
||||
|
||||
protected final ResourceFactory resourceFactory;
|
||||
|
||||
protected final Environment environment;
|
||||
|
||||
protected BootModule(Application application) {
|
||||
this.application = application;
|
||||
this.resourceFactory = Objects.requireNonNull(application.resourceFactory);
|
||||
this.environment = Objects.requireNonNull(application.getEnvironment());
|
||||
}
|
||||
|
||||
protected void removeEnvValue(String name) {
|
||||
application.envProperties.remove(name);
|
||||
}
|
||||
|
||||
protected void putEnvValue(Object name, Object value) {
|
||||
application.envProperties.put(name, value);
|
||||
}
|
||||
|
||||
protected List<ModuleEngine> getModuleEngines() {
|
||||
return application.getModuleEngines();
|
||||
}
|
||||
|
||||
protected void reconfigLogging(boolean first, Properties allProps) {
|
||||
application.loggingModule.reconfigLogging(first, allProps);
|
||||
}
|
||||
|
||||
protected void onEnvironmentChanged(String namespace, List<ResourceEvent> events) {
|
||||
if (namespace != null && namespace.contains("logging")) {
|
||||
//日志配置单独处理
|
||||
application.loggingModule.onEnvironmentUpdated(events);
|
||||
} else {
|
||||
application.onEnvironmentChanged(namespace, events);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,15 +32,13 @@ import org.redkale.util.Environment;
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class LoggingModule {
|
||||
|
||||
private final Application application;
|
||||
class LoggingModule extends BootModule {
|
||||
|
||||
//日志配置资源
|
||||
private final Properties loggingProperties = new Properties();
|
||||
|
||||
LoggingModule(Application application) {
|
||||
this.application = application;
|
||||
super(application);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,11 +76,11 @@ class LoggingModule {
|
||||
String searchRawHandler = "java.util.logging.SearchHandler";
|
||||
String searchReadHandler = LoggingSearchHandler.class.getName();
|
||||
Properties onlyLogProps = new Properties();
|
||||
Environment environment = application.getEnvironment();
|
||||
Environment envs = this.environment;
|
||||
allProps.entrySet().forEach(x -> {
|
||||
String key = x.getKey().toString();
|
||||
if (key.startsWith("java.util.logging.") || key.contains(".level") || key.equals("handlers")) {
|
||||
String val = environment.getPropertyValue(x.getValue().toString()
|
||||
String val = envs.getPropertyValue(x.getValue().toString()
|
||||
.replace("%m", "%tY%tm").replace("%d", "%tY%tm%td") //兼容旧时间格式
|
||||
.replace(searchRawHandler, searchReadHandler));
|
||||
onlyLogProps.put(key.replace(searchRawHandler, searchReadHandler), val);
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.redkale.convert.bson.BsonConvert;
|
||||
import org.redkale.convert.ext.*;
|
||||
import org.redkale.convert.json.JsonConvert;
|
||||
import org.redkale.convert.proto.ProtobufConvert;
|
||||
import org.redkale.convert.spi.ConvertProvider;
|
||||
import org.redkale.util.*;
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.redkale.convert;
|
||||
package org.redkale.convert.spi;
|
||||
|
||||
import org.redkale.convert.Convert;
|
||||
import org.redkale.convert.ConvertType;
|
||||
|
||||
/**
|
||||
* Convert的扩展实现类加载器, 通过此类可以创建自定义的序列化格式,例如:protobuf、xmlbean
|
||||
@@ -17,6 +17,7 @@ import java.util.function.*;
|
||||
import java.util.logging.*;
|
||||
import org.redkale.annotation.*;
|
||||
import org.redkale.convert.*;
|
||||
import org.redkale.inject.spi.ResourceAnnotationProvider;
|
||||
import org.redkale.util.Creator;
|
||||
import org.redkale.util.RedkaleClassLoader;
|
||||
import org.redkale.util.RedkaleException;
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.redkale.inject;
|
||||
package org.redkale.inject.spi;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
|
||||
/**
|
||||
* 自定义注入加载器
|
||||
@@ -22,10 +22,10 @@ import org.redkale.boot.ClassFilter;
|
||||
import org.redkale.boot.ModuleEngine;
|
||||
import org.redkale.boot.NodeServer;
|
||||
import org.redkale.convert.json.JsonConvert;
|
||||
import org.redkale.inject.ResourceAnnotationProvider;
|
||||
import org.redkale.inject.ResourceEvent;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.inject.ResourceTypeLoader;
|
||||
import org.redkale.inject.spi.ResourceAnnotationProvider;
|
||||
import org.redkale.mq.MessageConsumer;
|
||||
import org.redkale.mq.MessageManager;
|
||||
import org.redkale.mq.MessageProducer;
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
/*
|
||||
*/
|
||||
package org.redkale.boot;
|
||||
package org.redkale.props.spi;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.logging.Logger;
|
||||
import org.redkale.boot.Application;
|
||||
import org.redkale.inject.ResourceEvent;
|
||||
import org.redkale.props.spi.PropertiesModule;
|
||||
import org.redkale.util.*;
|
||||
|
||||
/**
|
||||
@@ -23,6 +25,8 @@ public abstract class PropertiesAgent {
|
||||
|
||||
protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName());
|
||||
|
||||
PropertiesModule bootModule;
|
||||
|
||||
/**
|
||||
* 编译时进行的操作
|
||||
*
|
||||
@@ -65,7 +69,7 @@ public abstract class PropertiesAgent {
|
||||
* @param events 变更项集合
|
||||
*/
|
||||
protected final void onEnvironmentUpdated(Application application, String namespace, List<ResourceEvent> events) {
|
||||
application.propertiesModule.onEnvironmentUpdated(namespace, events);
|
||||
bootModule.onEnvironmentUpdated(namespace, events);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
*/
|
||||
package org.redkale.boot;
|
||||
package org.redkale.props.spi;
|
||||
|
||||
import org.redkale.util.*;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
package org.redkale.boot;
|
||||
package org.redkale.props.spi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
@@ -16,6 +16,9 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.redkale.boot.Application;
|
||||
import org.redkale.boot.BootModule;
|
||||
import org.redkale.boot.ModuleEngine;
|
||||
import org.redkale.inject.ResourceEvent;
|
||||
import org.redkale.util.AnyValue;
|
||||
import org.redkale.util.Environment;
|
||||
@@ -34,12 +37,10 @@ import org.redkale.util.Utility;
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class PropertiesModule {
|
||||
public class PropertiesModule extends BootModule {
|
||||
|
||||
private final Logger logger = Logger.getLogger(this.getClass().getSimpleName());
|
||||
|
||||
private final Application application;
|
||||
|
||||
//配置源管理接口
|
||||
//@since 2.7.0
|
||||
private PropertiesAgent propertiesAgent;
|
||||
@@ -47,14 +48,14 @@ class PropertiesModule {
|
||||
//envProperties更新锁
|
||||
private final ReentrantLock updateLock = new ReentrantLock();
|
||||
|
||||
PropertiesModule(Application application) {
|
||||
this.application = application;
|
||||
public PropertiesModule(Application application) {
|
||||
super(application);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
if (this.propertiesAgent != null) {
|
||||
long s = System.currentTimeMillis();
|
||||
this.propertiesAgent.destroy(application.config.getAnyValue("properties"));
|
||||
this.propertiesAgent.destroy(application.getAppConfig().getAnyValue("properties"));
|
||||
logger.info(this.propertiesAgent.getClass().getSimpleName() + " destroy in " + (System.currentTimeMillis() - s) + " ms");
|
||||
}
|
||||
}
|
||||
@@ -92,7 +93,8 @@ class PropertiesModule {
|
||||
for (PropertiesAgentProvider provider : InstanceProvider.sort(providers)) {
|
||||
long s = System.currentTimeMillis();
|
||||
this.propertiesAgent = provider.createInstance();
|
||||
application.resourceFactory.inject(this.propertiesAgent);
|
||||
this.propertiesAgent.bootModule = this;
|
||||
application.getResourceFactory().inject(this.propertiesAgent);
|
||||
if (application.isCompileMode()) {
|
||||
this.propertiesAgent.compile(propsConf);
|
||||
} else {
|
||||
@@ -121,7 +123,7 @@ class PropertiesModule {
|
||||
|
||||
//重置远程日志配置
|
||||
if (Utility.isNotEmpty(logProps)) {
|
||||
application.loggingModule.reconfigLogging(false, logProps);
|
||||
reconfigLogging(false, logProps);
|
||||
}
|
||||
|
||||
if (!remoteEnvs.isEmpty()) {
|
||||
@@ -138,11 +140,11 @@ class PropertiesModule {
|
||||
try {
|
||||
if (namespace != null && namespace.contains("logging")) {
|
||||
//日志配置单独处理
|
||||
application.loggingModule.onEnvironmentUpdated(events);
|
||||
onEnvironmentUpdated(namespace, events);
|
||||
return;
|
||||
}
|
||||
Set<String> removedKeys = new HashSet<>();
|
||||
Properties newEnvs = new Properties(application.envProperties);
|
||||
Properties newEnvs = environment.newProperties();
|
||||
for (ResourceEvent<String> event : events) {
|
||||
if (event.newValue() != null) {
|
||||
newEnvs.put(event.name(), event.newValue());
|
||||
@@ -152,7 +154,7 @@ class PropertiesModule {
|
||||
}
|
||||
}
|
||||
mergeEnvProperties(newEnvs, removedKeys);
|
||||
application.onEnvironmentChanged(namespace, events);
|
||||
onEnvironmentChanged(namespace, events);
|
||||
} finally {
|
||||
updateLock.unlock();
|
||||
}
|
||||
@@ -186,49 +188,49 @@ class PropertiesModule {
|
||||
newMergeProps.put(k, v);
|
||||
} else { //其他视为普通配置项
|
||||
if (key.startsWith("system.property.")) {
|
||||
application.envProperties.put(k, v);
|
||||
putEnvValue(k, v);
|
||||
} else if (key.startsWith("mimetype.property.")) {
|
||||
application.envProperties.put(k, v);
|
||||
putEnvValue(k, v);
|
||||
} else if (key.startsWith("redkale.properties.property.")) {
|
||||
newMergeProps.put(k, v);
|
||||
String name = key.substring("redkale.properties.".length());
|
||||
application.envProperties.put(name, v);
|
||||
putEnvValue(name, v);
|
||||
} else if (key.startsWith("redkale.properties.property[")) {
|
||||
newMergeProps.put(k, v);
|
||||
String name = key.substring("redkale.properties[".length());
|
||||
name = name.substring(0, name.indexOf(']'));
|
||||
application.envProperties.put(name, v);
|
||||
putEnvValue(name, v);
|
||||
} else if (key.startsWith("redkale.properties.")) { //支持 -Dredkale.properties.mykey = myvalue
|
||||
String prefix = "redkale.properties.property[" + propertyIndex.getAndIncrement() + "]";
|
||||
String name = key.substring("redkale.properties.".length());
|
||||
newMergeProps.put(prefix + ".name", name);
|
||||
newMergeProps.put(prefix + ".value", v);
|
||||
application.envProperties.put(name, v);
|
||||
putEnvValue(name, v);
|
||||
} else { //独立的普通配置项文件,比如:config.properties文件中的配置项
|
||||
String prefix = "redkale.properties.property[" + propertyIndex.getAndIncrement() + "]";
|
||||
newMergeProps.put(prefix + ".name", k);
|
||||
newMergeProps.put(prefix + ".value", v);
|
||||
application.envProperties.put(k, v);
|
||||
putEnvValue(k, v);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (Utility.isNotEmpty(removedKeys)) {
|
||||
removedKeys.forEach(application.envProperties::remove);
|
||||
if (removedKeys != null && !removedKeys.isEmpty()) {
|
||||
removedKeys.forEach(this::removeEnvValue);
|
||||
}
|
||||
if (!newMergeProps.isEmpty()) {
|
||||
Properties newDyncProps = new Properties();
|
||||
newMergeProps.forEach((k, v) -> newDyncProps.put(k.toString(), application.getEnvironment().getPropertyValue(v.toString(), newMergeProps)));
|
||||
//合并配置
|
||||
application.getAppConfig().merge(AnyValue.loadFromProperties(newDyncProps).getAnyValue("redkale"), createMergeStrategy(application));
|
||||
application.getAppConfig().merge(AnyValue.loadFromProperties(newDyncProps).getAnyValue("redkale"), createMergeStrategy());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并系统配置项的策略
|
||||
*/
|
||||
static final AnyValue.MergeStrategy createMergeStrategy(final Application application) {
|
||||
AnyValue.MergeStrategy createMergeStrategy() {
|
||||
return (path, key, val1, val2) -> {
|
||||
for (ModuleEngine m : application.getModuleEngines()) {
|
||||
for (ModuleEngine m : getModuleEngines()) {
|
||||
AnyValue.MergeEnum rs = m.mergeAppConfigStrategy(path, key, val1, val2);
|
||||
if (rs != null) {
|
||||
return rs;
|
||||
@@ -4,13 +4,14 @@ package org.redkale.source;
|
||||
|
||||
import java.util.*;
|
||||
import org.redkale.annotation.AutoLoad;
|
||||
import org.redkale.annotation.ResourceChanged;
|
||||
import org.redkale.annotation.ResourceType;
|
||||
import org.redkale.inject.Resourcable;
|
||||
import org.redkale.inject.ResourceEvent;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.service.*;
|
||||
import org.redkale.source.spi.CacheSourceProvider;
|
||||
import org.redkale.util.*;
|
||||
import org.redkale.annotation.ResourceChanged;
|
||||
|
||||
/**
|
||||
* CacheSource的S抽象实现类 <br>
|
||||
|
||||
@@ -5,6 +5,7 @@ package org.redkale.source;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.IntFunction;
|
||||
import org.redkale.source.spi.DataNativeSqlParserProvider;
|
||||
import org.redkale.util.RedkaleClassLoader;
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,6 +10,7 @@ import java.net.*;
|
||||
import java.util.*;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.service.Service;
|
||||
import org.redkale.source.spi.DataSourceProvider;
|
||||
import org.redkale.util.*;
|
||||
import static org.redkale.util.Utility.isEmpty;
|
||||
|
||||
|
||||
71
src/main/java/org/redkale/source/SourceManager.java
Normal file
71
src/main/java/org/redkale/source/SourceManager.java
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
package org.redkale.source;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* source组件的基本管理器
|
||||
*
|
||||
* <p>
|
||||
* 详情见: https://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public interface SourceManager {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param sourceName 资源名
|
||||
*
|
||||
* @return CacheSource
|
||||
*/
|
||||
default CacheSource loadCacheSource(final String sourceName) {
|
||||
return loadCacheSource(sourceName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param sourceName 资源名
|
||||
* @param autoMemory 不存在是否自动创建内存版CacheSource
|
||||
*
|
||||
* @return CacheSource
|
||||
*/
|
||||
public CacheSource loadCacheSource(final String sourceName, boolean autoMemory);
|
||||
|
||||
/**
|
||||
* 获取所有CacheSource, 不同资源名可能指向同一个CacheSource
|
||||
*
|
||||
* @return CacheSource集合
|
||||
*/
|
||||
public Map<String, CacheSource> getCacheSources();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param sourceName 资源名
|
||||
*
|
||||
* @return DataSource
|
||||
*/
|
||||
default DataSource loadDataSource(final String sourceName) {
|
||||
return loadDataSource(sourceName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载DataSource
|
||||
*
|
||||
* @param sourceName 资源名
|
||||
* @param autoMemory 不存在是否自动创建内存版DataSource
|
||||
*
|
||||
* @return DataSource
|
||||
*/
|
||||
public DataSource loadDataSource(final String sourceName, boolean autoMemory);
|
||||
|
||||
/**
|
||||
* 获取所有DataSource, 不同资源名可能指向同一个DataSource
|
||||
*
|
||||
* @return DataSource集合
|
||||
*/
|
||||
public Map<String, DataSource> getDataSources();
|
||||
}
|
||||
@@ -3,8 +3,9 @@
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.redkale.source;
|
||||
package org.redkale.source.spi;
|
||||
|
||||
import org.redkale.source.CacheSource;
|
||||
import org.redkale.util.*;
|
||||
|
||||
/**
|
||||
@@ -1,8 +1,9 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
package org.redkale.source;
|
||||
package org.redkale.source.spi;
|
||||
|
||||
import org.redkale.source.DataNativeSqlParser;
|
||||
import org.redkale.util.InstanceProvider;
|
||||
|
||||
/**
|
||||
@@ -3,8 +3,9 @@
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.redkale.source;
|
||||
package org.redkale.source.spi;
|
||||
|
||||
import org.redkale.source.DataSource;
|
||||
import org.redkale.util.*;
|
||||
|
||||
/**
|
||||
@@ -1,14 +1,16 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
package org.redkale.source;
|
||||
package org.redkale.source.spi;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
import java.util.ServiceLoader;
|
||||
@@ -25,6 +27,18 @@ 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;
|
||||
import org.redkale.source.AbstractDataSource;
|
||||
import org.redkale.source.CacheMemorySource;
|
||||
import org.redkale.source.CacheSource;
|
||||
import org.redkale.source.DataJdbcSource;
|
||||
import org.redkale.source.DataMemorySource;
|
||||
import org.redkale.source.DataNativeSqlParser;
|
||||
import org.redkale.source.DataSource;
|
||||
import org.redkale.source.DataSources;
|
||||
import org.redkale.source.DataSqlSource;
|
||||
import org.redkale.source.SearchSource;
|
||||
import org.redkale.source.SourceManager;
|
||||
import org.redkale.util.AnyValue;
|
||||
import org.redkale.util.AnyValueWriter;
|
||||
import org.redkale.util.InstanceProvider;
|
||||
@@ -36,7 +50,7 @@ import org.redkale.util.Utility;
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public class SourceModuleEngine extends ModuleEngine {
|
||||
public class SourceModuleEngine extends ModuleEngine implements SourceManager {
|
||||
|
||||
//Source 原始的配置资源, 只会存在redkale.datasource(.|[) redkale.cachesource(.|[)开头的配置项
|
||||
private final Properties sourceProperties = new Properties();
|
||||
@@ -117,7 +131,7 @@ public class SourceModuleEngine extends ModuleEngine {
|
||||
this.resourceFactory.register(DataNativeSqlParser.class, this.nativeSqlParser);
|
||||
break; //only first provider
|
||||
}
|
||||
|
||||
resourceFactory.register(SourceManager.class, this);
|
||||
//--------------------------------- 注册 DataSource、CacheSource ---------------------------------
|
||||
resourceFactory.register(new DataSourceLoader(), DataSource.class);
|
||||
resourceFactory.register(new CacheSourceLoader(), CacheSource.class);
|
||||
@@ -330,6 +344,17 @@ public class SourceModuleEngine extends ModuleEngine {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有CacheSource, 不同资源名可能指向同一个CacheSource
|
||||
*
|
||||
* @return CacheSource集合
|
||||
*/
|
||||
public Map<String, CacheSource> getCacheSources() {
|
||||
Map<String, CacheSource> sources = new HashMap<>();
|
||||
cacheSources.forEach(v -> sources.put(v.resourceName(), v));
|
||||
return sources;
|
||||
}
|
||||
|
||||
public CacheSource loadCacheSource(final String sourceName, boolean autoMemory) {
|
||||
cacheSourceLock.lock();
|
||||
try {
|
||||
@@ -378,6 +403,17 @@ public class SourceModuleEngine extends ModuleEngine {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有DataSource, 不同资源名可能指向同一个DataSource
|
||||
*
|
||||
* @return DataSource集合
|
||||
*/
|
||||
public Map<String, DataSource> getDataSources() {
|
||||
Map<String, DataSource> sources = new HashMap<>();
|
||||
dataSources.forEach(v -> sources.put(v.resourceName(), v));
|
||||
return sources;
|
||||
}
|
||||
|
||||
public DataSource loadDataSource(final String sourceName, boolean autoMemory) {
|
||||
dataSourceLock.lock();
|
||||
try {
|
||||
@@ -27,6 +27,10 @@ public class Environment implements java.io.Serializable {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public Properties newProperties() {
|
||||
return new Properties(properties);
|
||||
}
|
||||
|
||||
public Set<String> keySet() {
|
||||
return (Set) properties.keySet();
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ public class RedkaleClassLoader extends URLClassLoader {
|
||||
"org.redkale.convert.ext",
|
||||
"org.redkale.convert.json",
|
||||
"org.redkale.convert.proto",
|
||||
"org.redkale.convert.spi",
|
||||
"org.redkale.inject",
|
||||
"org.redkale.lock",
|
||||
"org.redkale.lock.spi",
|
||||
@@ -70,6 +71,7 @@ public class RedkaleClassLoader extends URLClassLoader {
|
||||
"org.redkale.schedule.spi",
|
||||
"org.redkale.service",
|
||||
"org.redkale.source",
|
||||
"org.redkale.source.spi",
|
||||
"org.redkale.util",
|
||||
"org.redkale.watch"
|
||||
};
|
||||
|
||||
@@ -12,8 +12,8 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
import java.lang.reflect.Field;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.redkale.convert.json.JsonConvert;
|
||||
import org.redkale.inject.ResourceAnnotationProvider;
|
||||
import org.redkale.inject.ResourceFactory;
|
||||
import org.redkale.inject.spi.ResourceAnnotationProvider;
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user