BootModule

This commit is contained in:
redkale
2023-12-25 19:09:13 +08:00
parent 710f8fc632
commit 498b2ff70f
26 changed files with 256 additions and 66 deletions

View File

@@ -1,7 +1,7 @@
![Redkale logo](docs/images/logo.png) ![Redkale logo](docs/images/logo.png)
## 简介 ## 简介
    Redkale (中文名: 红菜苔,一种湖北特产蔬菜) 是基于Java 11全新的微服务框架 包含HTTP、WebSocket、TCP/UDP、数据序列化、数据缓存、依赖注入等功能。 本框架致力于简化集中式和微服务架构的开发,在增强开发敏捷性的同时保持高性能。   Redkale (中文名: 红菜苔,一种湖北特产蔬菜) 是基于Java 11全新的微服务框架 包含HTTP、WebSocket、TCP/UDP、数据序列化、数据缓存、依赖注入等功能。 本框架致力于简化集中式和微服务架构的开发,在增强开发敏捷性的同时保持高性能。
主要特点:: 主要特点::
* 大量使用Java 8+新特性接口默认值、Stream、Lambda、内置的ASM、HttpClient等 * 大量使用Java 8+新特性接口默认值、Stream、Lambda、内置的ASM、HttpClient等
@@ -25,12 +25,12 @@
* [FAQ](docs/faq.md) * [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在接口定义上使用了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显得很简单这体现了Redkale的简易性而并非是不足从一个良好的设计习惯或架构上来看有些常用功能是不需要提供的如Redkale的HTTP服务不支持JSP, JSP其实算是一个落后的技术现在是一个多样化终端的时代终端不只局限于桌面程序和PC浏览器还有原生App、混合式App、微信端、移动H5、提供第三方接口等各种形式的终端这些都不是JSP能方便兼顾的而HTTP+JSON作为通用性接口可以避免重复开发模版引擎的功能加上各种强大的JS框架足以取代JSP。Redkale在功能上做了筛选不会为了迎合主流而提供而是以良好的设计思想为指导。这是Redkale的主导思维。
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>详情请访问:&nbsp;&nbsp;&nbsp;&nbsp;<a href='https://redkale.org' target='_blank'>https://redkale.org</a></b> &emsp;&emsp;&emsp;<b>详情请访问:&emsp;&emsp;<a href='https://redkale.org' target='_blank'>https://redkale.org</a></b>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>基本文档:&nbsp;&nbsp;&nbsp;&nbsp;<a href='https://redkale.org/articles.html' target='_blank'>https://redkale.org/articles.html</a></b> &emsp;&emsp;&emsp;<b>基本文档:&emsp;&emsp;<a href='https://redkale.org/articles.html' target='_blank'>https://redkale.org/articles.html</a></b>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>欢迎加入Redkale QQ群: 527523235</b> &emsp;&emsp;&emsp;<b>欢迎加入Redkale QQ群: 527523235</b>
&nbsp; &nbsp;

View File

@@ -20,14 +20,14 @@
# 创建工程 # 创建工程
在IDE中使用ant或maven方式创建工程增加redkale的依赖。下载解压 在IDE中使用ant或maven方式创建工程增加redkale的依赖。下载解压
&nbsp;&nbsp;&nbsp;&nbsp;![home](images/home-dir.png) &emsp;&emsp;![home](images/home-dir.png)
并覆盖到工程目录下。 并覆盖到工程目录下。
* bin 存放启动/关闭脚本(start.sh、shutdown.sh、redkale.sh等) * bin 存放启动/关闭脚本(start.sh、shutdown.sh、redkale.sh等)
* conf 存放服务器所需配置文件: * conf 存放服务器所需配置文件:
* &nbsp;&nbsp;&nbsp;&nbsp; application.xml &nbsp;&nbsp;服务配置文件 (必需) * &emsp;&emsp; application.xml &nbsp;&nbsp;服务配置文件 (必需)
* &nbsp;&nbsp;&nbsp;&nbsp; logging.properties日志配置文件 (可选) * &emsp;&emsp; logging.properties日志配置文件 (可选)
* &nbsp;&nbsp;&nbsp;&nbsp; source.properties 数据库配置文件 (可选) * &emsp;&emsp; source.properties 数据库配置文件 (可选)
* lib 存放服务所依赖jar * lib 存放服务所依赖jar
* logs logging.properties配置中默认的日志存放目录。 * logs logging.properties配置中默认的日志存放目录。
@@ -55,7 +55,7 @@ public class HelloService implements Service {
``` ```
运行结果: 运行结果:
&nbsp;&nbsp;&nbsp;&nbsp;![console](images/hello-console.png) &emsp;&emsp;![console](images/hello-console.png)
# 进一步阅读 # 进一步阅读
* 详细的配置说明看[这里](config.md)。 * 详细的配置说明看[这里](config.md)。

View File

@@ -1,8 +1,8 @@
# Service组件 # Service组件
>Service是Redkale最核心的组件主要处理业务逻辑和操作数据层。Service实例分两种模式: <b>本地模式</b><b>远程模式</b>。其模式由```conf/application.xml```文件来配置。开发人员在调用过程中通常不需要区分Service实例是哪种模式。 <br/> &emsp;&emsp;Service是Redkale最核心的组件主要处理业务逻辑和操作数据层。Service实例分两种模式: <b>本地模式</b><b>远程模式</b>。其模式由```conf/application.xml```文件来配置。开发人员在调用过程中通常不需要区分Service实例是哪种模式。 <br/>
>并不是Sevice都能进行本地和远程模式切换 以下情况的Service不能转成远程模式: &emsp;&emsp;并不是Sevice都能进行本地和远程模式切换 以下情况的Service不能转成远程模式:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、Service类修饰为```final``` <br> &emsp;&emsp;&emsp;&emsp; 1、Service类修饰为```final``` <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、Service类被标记```@Local``` <br> &emsp;&emsp;&emsp;&emsp; 2、Service类被标记```@Local``` <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3、Service类被标记```@Component``` <br> &emsp;&emsp;&emsp;&emsp; 3、Service类被标记```@Component``` <br>
&nbsp;&nbsp;&nbsp;&nbsp;Redkale进程启动时扫描可加载的Service实现类根据配置文件配置的模式采用```ASM```技术动态生成相应的Service临时类进行实例化并注册到ResourceFactory同其他Service、Servlet依赖注入。 &emsp;&emsp;Redkale进程启动时扫描可加载的Service实现类根据配置文件配置的模式采用```ASM```技术动态生成相应的Service临时类进行实例化并注册到ResourceFactory同其他Service、Servlet依赖注入。

View File

@@ -26,7 +26,9 @@ module org.redkale {
exports org.redkale.convert.ext; exports org.redkale.convert.ext;
exports org.redkale.convert.json; exports org.redkale.convert.json;
exports org.redkale.convert.proto; exports org.redkale.convert.proto;
exports org.redkale.convert.spi;
exports org.redkale.inject; exports org.redkale.inject;
exports org.redkale.inject.spi;
exports org.redkale.lock; exports org.redkale.lock;
exports org.redkale.lock.spi; exports org.redkale.lock.spi;
exports org.redkale.mq; exports org.redkale.mq;
@@ -36,22 +38,24 @@ module org.redkale {
exports org.redkale.net.http; exports org.redkale.net.http;
exports org.redkale.net.sncp; exports org.redkale.net.sncp;
exports org.redkale.persistence; exports org.redkale.persistence;
exports org.redkale.props.spi;
exports org.redkale.schedule; exports org.redkale.schedule;
exports org.redkale.schedule.spi; exports org.redkale.schedule.spi;
exports org.redkale.service; exports org.redkale.service;
exports org.redkale.source; exports org.redkale.source;
exports org.redkale.source.spi;
exports org.redkale.util; exports org.redkale.util;
exports org.redkale.watch; exports org.redkale.watch;
uses org.redkale.boot.PropertiesAgentProvider; uses org.redkale.props.spi.PropertiesAgentProvider;
uses org.redkale.cache.spi.CacheManagerProvider; uses org.redkale.cache.spi.CacheManagerProvider;
uses org.redkale.cluster.spi.ClusterAgentProvider; uses org.redkale.cluster.spi.ClusterAgentProvider;
uses org.redkale.convert.ConvertProvider; uses org.redkale.convert.spi.ConvertProvider;
uses org.redkale.inject.ResourceAnnotationProvider; uses org.redkale.inject.spi.ResourceAnnotationProvider;
uses org.redkale.mq.spi.MessageAgentProvider; uses org.redkale.mq.spi.MessageAgentProvider;
uses org.redkale.schedule.spi.ScheduleManagerProvider; uses org.redkale.schedule.spi.ScheduleManagerProvider;
uses org.redkale.source.CacheSourceProvider; uses org.redkale.source.spi.CacheSourceProvider;
uses org.redkale.source.DataSourceProvider; uses org.redkale.source.spi.DataSourceProvider;
uses org.redkale.source.DataNativeSqlParserProvider; uses org.redkale.source.spi.DataNativeSqlParserProvider;
} }

View File

@@ -42,9 +42,11 @@ import org.redkale.mq.spi.MessageModuleEngine;
import org.redkale.net.*; import org.redkale.net.*;
import org.redkale.net.http.*; import org.redkale.net.http.*;
import org.redkale.net.sncp.*; import org.redkale.net.sncp.*;
import org.redkale.props.spi.PropertiesModule;
import org.redkale.schedule.spi.ScheduleModuleEngine; import org.redkale.schedule.spi.ScheduleModuleEngine;
import org.redkale.service.Service; import org.redkale.service.Service;
import org.redkale.source.*; import org.redkale.source.*;
import org.redkale.source.spi.SourceModuleEngine;
import org.redkale.util.*; import org.redkale.util.*;
import org.redkale.watch.WatchServlet; import org.redkale.watch.WatchServlet;

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

View File

@@ -32,15 +32,13 @@ import org.redkale.util.Environment;
* *
* @since 2.8.0 * @since 2.8.0
*/ */
class LoggingModule { class LoggingModule extends BootModule {
private final Application application;
//日志配置资源 //日志配置资源
private final Properties loggingProperties = new Properties(); private final Properties loggingProperties = new Properties();
LoggingModule(Application application) { LoggingModule(Application application) {
this.application = application; super(application);
} }
/** /**
@@ -78,11 +76,11 @@ class LoggingModule {
String searchRawHandler = "java.util.logging.SearchHandler"; String searchRawHandler = "java.util.logging.SearchHandler";
String searchReadHandler = LoggingSearchHandler.class.getName(); String searchReadHandler = LoggingSearchHandler.class.getName();
Properties onlyLogProps = new Properties(); Properties onlyLogProps = new Properties();
Environment environment = application.getEnvironment(); Environment envs = this.environment;
allProps.entrySet().forEach(x -> { allProps.entrySet().forEach(x -> {
String key = x.getKey().toString(); String key = x.getKey().toString();
if (key.startsWith("java.util.logging.") || key.contains(".level") || key.equals("handlers")) { 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("%m", "%tY%tm").replace("%d", "%tY%tm%td") //兼容旧时间格式
.replace(searchRawHandler, searchReadHandler)); .replace(searchRawHandler, searchReadHandler));
onlyLogProps.put(key.replace(searchRawHandler, searchReadHandler), val); onlyLogProps.put(key.replace(searchRawHandler, searchReadHandler), val);

View File

@@ -22,6 +22,7 @@ import org.redkale.convert.bson.BsonConvert;
import org.redkale.convert.ext.*; import org.redkale.convert.ext.*;
import org.redkale.convert.json.JsonConvert; import org.redkale.convert.json.JsonConvert;
import org.redkale.convert.proto.ProtobufConvert; import org.redkale.convert.proto.ProtobufConvert;
import org.redkale.convert.spi.ConvertProvider;
import org.redkale.util.*; import org.redkale.util.*;
/** /**

View File

@@ -3,7 +3,10 @@
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * 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的扩展实现类加载器, 通过此类可以创建自定义的序列化格式例如protobufxmlbean * Convert的扩展实现类加载器, 通过此类可以创建自定义的序列化格式例如protobufxmlbean

View File

@@ -17,6 +17,7 @@ import java.util.function.*;
import java.util.logging.*; import java.util.logging.*;
import org.redkale.annotation.*; import org.redkale.annotation.*;
import org.redkale.convert.*; import org.redkale.convert.*;
import org.redkale.inject.spi.ResourceAnnotationProvider;
import org.redkale.util.Creator; import org.redkale.util.Creator;
import org.redkale.util.RedkaleClassLoader; import org.redkale.util.RedkaleClassLoader;
import org.redkale.util.RedkaleException; import org.redkale.util.RedkaleException;

View File

@@ -3,10 +3,11 @@
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package org.redkale.inject; package org.redkale.inject.spi;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import org.redkale.inject.ResourceFactory;
/** /**
* 自定义注入加载器 * 自定义注入加载器

View File

@@ -22,10 +22,10 @@ import org.redkale.boot.ClassFilter;
import org.redkale.boot.ModuleEngine; import org.redkale.boot.ModuleEngine;
import org.redkale.boot.NodeServer; import org.redkale.boot.NodeServer;
import org.redkale.convert.json.JsonConvert; import org.redkale.convert.json.JsonConvert;
import org.redkale.inject.ResourceAnnotationProvider;
import org.redkale.inject.ResourceEvent; import org.redkale.inject.ResourceEvent;
import org.redkale.inject.ResourceFactory; import org.redkale.inject.ResourceFactory;
import org.redkale.inject.ResourceTypeLoader; import org.redkale.inject.ResourceTypeLoader;
import org.redkale.inject.spi.ResourceAnnotationProvider;
import org.redkale.mq.MessageConsumer; import org.redkale.mq.MessageConsumer;
import org.redkale.mq.MessageManager; import org.redkale.mq.MessageManager;
import org.redkale.mq.MessageProducer; import org.redkale.mq.MessageProducer;

View File

@@ -1,10 +1,12 @@
/* /*
*/ */
package org.redkale.boot; package org.redkale.props.spi;
import java.util.*; import java.util.*;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.redkale.boot.Application;
import org.redkale.inject.ResourceEvent; import org.redkale.inject.ResourceEvent;
import org.redkale.props.spi.PropertiesModule;
import org.redkale.util.*; import org.redkale.util.*;
/** /**
@@ -23,6 +25,8 @@ public abstract class PropertiesAgent {
protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName()); protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName());
PropertiesModule bootModule;
/** /**
* 编译时进行的操作 * 编译时进行的操作
* *
@@ -65,7 +69,7 @@ public abstract class PropertiesAgent {
* @param events 变更项集合 * @param events 变更项集合
*/ */
protected final void onEnvironmentUpdated(Application application, String namespace, List<ResourceEvent> events) { protected final void onEnvironmentUpdated(Application application, String namespace, List<ResourceEvent> events) {
application.propertiesModule.onEnvironmentUpdated(namespace, events); bootModule.onEnvironmentUpdated(namespace, events);
} }
} }

View File

@@ -1,6 +1,6 @@
/* /*
*/ */
package org.redkale.boot; package org.redkale.props.spi;
import org.redkale.util.*; import org.redkale.util.*;

View File

@@ -1,7 +1,7 @@
/* /*
* *
*/ */
package org.redkale.boot; package org.redkale.props.spi;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
@@ -16,6 +16,9 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; 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.inject.ResourceEvent;
import org.redkale.util.AnyValue; import org.redkale.util.AnyValue;
import org.redkale.util.Environment; import org.redkale.util.Environment;
@@ -34,12 +37,10 @@ import org.redkale.util.Utility;
* *
* @since 2.8.0 * @since 2.8.0
*/ */
class PropertiesModule { public class PropertiesModule extends BootModule {
private final Logger logger = Logger.getLogger(this.getClass().getSimpleName()); private final Logger logger = Logger.getLogger(this.getClass().getSimpleName());
private final Application application;
//配置源管理接口 //配置源管理接口
//@since 2.7.0 //@since 2.7.0
private PropertiesAgent propertiesAgent; private PropertiesAgent propertiesAgent;
@@ -47,14 +48,14 @@ class PropertiesModule {
//envProperties更新锁 //envProperties更新锁
private final ReentrantLock updateLock = new ReentrantLock(); private final ReentrantLock updateLock = new ReentrantLock();
PropertiesModule(Application application) { public PropertiesModule(Application application) {
this.application = application; super(application);
} }
public void destroy() { public void destroy() {
if (this.propertiesAgent != null) { if (this.propertiesAgent != null) {
long s = System.currentTimeMillis(); 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"); logger.info(this.propertiesAgent.getClass().getSimpleName() + " destroy in " + (System.currentTimeMillis() - s) + " ms");
} }
} }
@@ -92,7 +93,8 @@ class PropertiesModule {
for (PropertiesAgentProvider provider : InstanceProvider.sort(providers)) { for (PropertiesAgentProvider provider : InstanceProvider.sort(providers)) {
long s = System.currentTimeMillis(); long s = System.currentTimeMillis();
this.propertiesAgent = provider.createInstance(); this.propertiesAgent = provider.createInstance();
application.resourceFactory.inject(this.propertiesAgent); this.propertiesAgent.bootModule = this;
application.getResourceFactory().inject(this.propertiesAgent);
if (application.isCompileMode()) { if (application.isCompileMode()) {
this.propertiesAgent.compile(propsConf); this.propertiesAgent.compile(propsConf);
} else { } else {
@@ -121,7 +123,7 @@ class PropertiesModule {
//重置远程日志配置 //重置远程日志配置
if (Utility.isNotEmpty(logProps)) { if (Utility.isNotEmpty(logProps)) {
application.loggingModule.reconfigLogging(false, logProps); reconfigLogging(false, logProps);
} }
if (!remoteEnvs.isEmpty()) { if (!remoteEnvs.isEmpty()) {
@@ -138,11 +140,11 @@ class PropertiesModule {
try { try {
if (namespace != null && namespace.contains("logging")) { if (namespace != null && namespace.contains("logging")) {
//日志配置单独处理 //日志配置单独处理
application.loggingModule.onEnvironmentUpdated(events); onEnvironmentUpdated(namespace, events);
return; return;
} }
Set<String> removedKeys = new HashSet<>(); Set<String> removedKeys = new HashSet<>();
Properties newEnvs = new Properties(application.envProperties); Properties newEnvs = environment.newProperties();
for (ResourceEvent<String> event : events) { for (ResourceEvent<String> event : events) {
if (event.newValue() != null) { if (event.newValue() != null) {
newEnvs.put(event.name(), event.newValue()); newEnvs.put(event.name(), event.newValue());
@@ -152,7 +154,7 @@ class PropertiesModule {
} }
} }
mergeEnvProperties(newEnvs, removedKeys); mergeEnvProperties(newEnvs, removedKeys);
application.onEnvironmentChanged(namespace, events); onEnvironmentChanged(namespace, events);
} finally { } finally {
updateLock.unlock(); updateLock.unlock();
} }
@@ -186,49 +188,49 @@ class PropertiesModule {
newMergeProps.put(k, v); newMergeProps.put(k, v);
} else { //其他视为普通配置项 } else { //其他视为普通配置项
if (key.startsWith("system.property.")) { if (key.startsWith("system.property.")) {
application.envProperties.put(k, v); putEnvValue(k, v);
} else if (key.startsWith("mimetype.property.")) { } else if (key.startsWith("mimetype.property.")) {
application.envProperties.put(k, v); putEnvValue(k, v);
} else if (key.startsWith("redkale.properties.property.")) { } else if (key.startsWith("redkale.properties.property.")) {
newMergeProps.put(k, v); newMergeProps.put(k, v);
String name = key.substring("redkale.properties.".length()); String name = key.substring("redkale.properties.".length());
application.envProperties.put(name, v); putEnvValue(name, v);
} else if (key.startsWith("redkale.properties.property[")) { } else if (key.startsWith("redkale.properties.property[")) {
newMergeProps.put(k, v); newMergeProps.put(k, v);
String name = key.substring("redkale.properties[".length()); String name = key.substring("redkale.properties[".length());
name = name.substring(0, name.indexOf(']')); name = name.substring(0, name.indexOf(']'));
application.envProperties.put(name, v); putEnvValue(name, v);
} else if (key.startsWith("redkale.properties.")) { //支持 -Dredkale.properties.mykey = myvalue } else if (key.startsWith("redkale.properties.")) { //支持 -Dredkale.properties.mykey = myvalue
String prefix = "redkale.properties.property[" + propertyIndex.getAndIncrement() + "]"; String prefix = "redkale.properties.property[" + propertyIndex.getAndIncrement() + "]";
String name = key.substring("redkale.properties.".length()); String name = key.substring("redkale.properties.".length());
newMergeProps.put(prefix + ".name", name); newMergeProps.put(prefix + ".name", name);
newMergeProps.put(prefix + ".value", v); newMergeProps.put(prefix + ".value", v);
application.envProperties.put(name, v); putEnvValue(name, v);
} else { //独立的普通配置项文件比如config.properties文件中的配置项 } else { //独立的普通配置项文件比如config.properties文件中的配置项
String prefix = "redkale.properties.property[" + propertyIndex.getAndIncrement() + "]"; String prefix = "redkale.properties.property[" + propertyIndex.getAndIncrement() + "]";
newMergeProps.put(prefix + ".name", k); newMergeProps.put(prefix + ".name", k);
newMergeProps.put(prefix + ".value", v); newMergeProps.put(prefix + ".value", v);
application.envProperties.put(k, v); putEnvValue(k, v);
} }
} }
}); });
if (Utility.isNotEmpty(removedKeys)) { if (removedKeys != null && !removedKeys.isEmpty()) {
removedKeys.forEach(application.envProperties::remove); removedKeys.forEach(this::removeEnvValue);
} }
if (!newMergeProps.isEmpty()) { if (!newMergeProps.isEmpty()) {
Properties newDyncProps = new Properties(); Properties newDyncProps = new Properties();
newMergeProps.forEach((k, v) -> newDyncProps.put(k.toString(), application.getEnvironment().getPropertyValue(v.toString(), newMergeProps))); 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) -> { return (path, key, val1, val2) -> {
for (ModuleEngine m : application.getModuleEngines()) { for (ModuleEngine m : getModuleEngines()) {
AnyValue.MergeEnum rs = m.mergeAppConfigStrategy(path, key, val1, val2); AnyValue.MergeEnum rs = m.mergeAppConfigStrategy(path, key, val1, val2);
if (rs != null) { if (rs != null) {
return rs; return rs;

View File

@@ -4,13 +4,14 @@ package org.redkale.source;
import java.util.*; import java.util.*;
import org.redkale.annotation.AutoLoad; import org.redkale.annotation.AutoLoad;
import org.redkale.annotation.ResourceChanged;
import org.redkale.annotation.ResourceType; import org.redkale.annotation.ResourceType;
import org.redkale.inject.Resourcable; import org.redkale.inject.Resourcable;
import org.redkale.inject.ResourceEvent; import org.redkale.inject.ResourceEvent;
import org.redkale.inject.ResourceFactory; import org.redkale.inject.ResourceFactory;
import org.redkale.service.*; import org.redkale.service.*;
import org.redkale.source.spi.CacheSourceProvider;
import org.redkale.util.*; import org.redkale.util.*;
import org.redkale.annotation.ResourceChanged;
/** /**
* CacheSource的S抽象实现类 <br> * CacheSource的S抽象实现类 <br>

View File

@@ -5,6 +5,7 @@ package org.redkale.source;
import java.util.*; import java.util.*;
import java.util.function.IntFunction; import java.util.function.IntFunction;
import org.redkale.source.spi.DataNativeSqlParserProvider;
import org.redkale.util.RedkaleClassLoader; import org.redkale.util.RedkaleClassLoader;
/** /**

View File

@@ -10,6 +10,7 @@ import java.net.*;
import java.util.*; import java.util.*;
import org.redkale.inject.ResourceFactory; import org.redkale.inject.ResourceFactory;
import org.redkale.service.Service; import org.redkale.service.Service;
import org.redkale.source.spi.DataSourceProvider;
import org.redkale.util.*; import org.redkale.util.*;
import static org.redkale.util.Utility.isEmpty; import static org.redkale.util.Utility.isEmpty;

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

View File

@@ -3,8 +3,9 @@
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * 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.*; import org.redkale.util.*;
/** /**

View File

@@ -1,8 +1,9 @@
/* /*
* *
*/ */
package org.redkale.source; package org.redkale.source.spi;
import org.redkale.source.DataNativeSqlParser;
import org.redkale.util.InstanceProvider; import org.redkale.util.InstanceProvider;
/** /**

View File

@@ -3,8 +3,9 @@
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * 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.*; import org.redkale.util.*;
/** /**

View File

@@ -1,14 +1,16 @@
/* /*
* *
*/ */
package org.redkale.source; package org.redkale.source.spi;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Properties; import java.util.Properties;
import java.util.ServiceLoader; import java.util.ServiceLoader;
@@ -25,6 +27,18 @@ import org.redkale.inject.ResourceTypeLoader;
import org.redkale.net.Servlet; import org.redkale.net.Servlet;
import org.redkale.net.sncp.Sncp; import org.redkale.net.sncp.Sncp;
import org.redkale.service.Service; import org.redkale.service.Service;
import org.redkale.source.AbstractCacheSource;
import org.redkale.source.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.AnyValue;
import org.redkale.util.AnyValueWriter; import org.redkale.util.AnyValueWriter;
import org.redkale.util.InstanceProvider; import org.redkale.util.InstanceProvider;
@@ -36,7 +50,7 @@ import org.redkale.util.Utility;
* *
* @author zhangjx * @author zhangjx
*/ */
public class SourceModuleEngine extends ModuleEngine { public class SourceModuleEngine extends ModuleEngine implements SourceManager {
//Source 原始的配置资源, 只会存在redkale.datasource(.|[) redkale.cachesource(.|[)开头的配置项 //Source 原始的配置资源, 只会存在redkale.datasource(.|[) redkale.cachesource(.|[)开头的配置项
private final Properties sourceProperties = new Properties(); private final Properties sourceProperties = new Properties();
@@ -117,7 +131,7 @@ public class SourceModuleEngine extends ModuleEngine {
this.resourceFactory.register(DataNativeSqlParser.class, this.nativeSqlParser); this.resourceFactory.register(DataNativeSqlParser.class, this.nativeSqlParser);
break; //only first provider break; //only first provider
} }
resourceFactory.register(SourceManager.class, this);
//--------------------------------- 注册 DataSourceCacheSource --------------------------------- //--------------------------------- 注册 DataSourceCacheSource ---------------------------------
resourceFactory.register(new DataSourceLoader(), DataSource.class); resourceFactory.register(new DataSourceLoader(), DataSource.class);
resourceFactory.register(new CacheSourceLoader(), CacheSource.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) { public CacheSource loadCacheSource(final String sourceName, boolean autoMemory) {
cacheSourceLock.lock(); cacheSourceLock.lock();
try { 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) { public DataSource loadDataSource(final String sourceName, boolean autoMemory) {
dataSourceLock.lock(); dataSourceLock.lock();
try { try {

View File

@@ -27,6 +27,10 @@ public class Environment implements java.io.Serializable {
this.properties = properties; this.properties = properties;
} }
public Properties newProperties() {
return new Properties(properties);
}
public Set<String> keySet() { public Set<String> keySet() {
return (Set) properties.keySet(); return (Set) properties.keySet();
} }

View File

@@ -56,6 +56,7 @@ public class RedkaleClassLoader extends URLClassLoader {
"org.redkale.convert.ext", "org.redkale.convert.ext",
"org.redkale.convert.json", "org.redkale.convert.json",
"org.redkale.convert.proto", "org.redkale.convert.proto",
"org.redkale.convert.spi",
"org.redkale.inject", "org.redkale.inject",
"org.redkale.lock", "org.redkale.lock",
"org.redkale.lock.spi", "org.redkale.lock.spi",
@@ -70,6 +71,7 @@ public class RedkaleClassLoader extends URLClassLoader {
"org.redkale.schedule.spi", "org.redkale.schedule.spi",
"org.redkale.service", "org.redkale.service",
"org.redkale.source", "org.redkale.source",
"org.redkale.source.spi",
"org.redkale.util", "org.redkale.util",
"org.redkale.watch" "org.redkale.watch"
}; };

View File

@@ -12,8 +12,8 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import org.junit.jupiter.api.*; import org.junit.jupiter.api.*;
import org.redkale.convert.json.JsonConvert; import org.redkale.convert.json.JsonConvert;
import org.redkale.inject.ResourceAnnotationProvider;
import org.redkale.inject.ResourceFactory; import org.redkale.inject.ResourceFactory;
import org.redkale.inject.spi.ResourceAnnotationProvider;
/** /**
* *