# tiny
**Repository Path**: zhouzhou5/tiny
## Basic Information
- **Project Name**: tiny
- **Description**: 小巧的java应用微内核框架, 可用于构建小工具项目,web项目,各种大大小小的项目
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 15
- **Created**: 2021-10-20
- **Last Updated**: 2021-10-20
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 介绍
小巧的java应用微内核框架. 基于 [enet](https://gitee.com/xnat/enet) 事件环型框架结构
> 系统只一个公用线程池: 所有的执行都被抽象成Runnable加入到公用线程池中执行
> > 系统中的任务只有在线程池到达最大后,才需要排对执行(和默认线程池的行为不同)
> 上层业务不需要创建线程池和线程增加复杂度, 而使用Devourer控制执行并发
> 所以系统性能只由线程池大小属性 sys.exec.corePoolSize=8, sys.exec.maximumPoolSize=30 和 jvm内存参数 -Xmx512m 控制

# 安装教程
```xml
cn.xnatural.app
tiny
1.0.9
```
# 可搭配其它服务
[http](https://gitee.com/xnat/http), [jpa](https://gitee.com/xnat/jpa),
[sched](https://gitee.com/xnat/sched), [remoter](https://gitee.com/xnat/remoter)
# 初始化
```java
final AppContext app = new AppContext(); // 创建一个应用
app.addSource(new ServerTpl("server1") { // 添加服务 server1
@EL(name = "sys.starting")
void start() {
log.info("{} start", name);
}
});
app.addSource(new TestService()); // 添加自定义服务
app.start(); // 应用启动(会依次触发系统事件)
```
> 基于事件环型框架结构图
>
> > 以AppContext#EP为事件中心挂载服务结构

## 系统事件: app.start() 后会依次触发 sys.inited, sys.starting, sys.started
+ sys.inited: 应用始化完成(环境配置, 系统线程池, 事件中心)
+ sys.starting: 通知所有服务启动. 一般为ServerTpl
+ sys.started: 应用启动完成
+ sys.stopping: 应用停止事件(kill pid)
## 环境配置
>+ 系统属性(-Dconfigname): configname 指定配置文件名. 默认:app
>+ 系统属性(-Dprofile): profile 指定启用特定的配置
>+ 系统属性(-Dconfigdir): configdir 指定额外配置文件目录
* 只读取properties文件. 按顺序读取app.properties, app-[profile].properties 两个配置文件
* 配置文件支持简单的 ${} 属性替换
> 加载顺序(优先级从低到高):
* classpath:app.properties, classpath:app-[profile].properties
* file:./app.properties, file:./app-[profile].properties
* configdir:app.properties, configdir:app-[profile].properties
* 自定义环境配置(重写方法): AppContext#customEnv(Map)
* System.getProperties()
## 添加 [http](https://gitee.com/xnat/http) 服务
```properties
### app.propertiees
web.hp=:8080
```
```java
app.addSource(new ServerTpl("web") { //添加web服务
HttpServer server;
@EL(name = "sys.starting", async = true)
void start() {
server = new HttpServer(app().attrs(name), exec());
server.buildChain(chain -> {
chain.get("get", hCtx -> {
hCtx.render("xxxxxxxxxxxx");
});
}).start();
}
@EL(name = "sys.stopping")
void stop() {
if (server != null) server.stop();
}
});
```
## 添加 [jpa](https://gitee.com/xnat/jpa)
```properties
### app.properties
jpa_local.url=jdbc:mysql://localhost:3306/test?useSSL=false&user=root&password=root
```
```java
app.addSource(new ServerTpl("jpa_local") { //数据库 jpa_local
Repo repo;
@EL(name = "sys.starting", async = true)
void start() {
repo = new Repo(attrs()).init();
exposeBean(repo); // 把repo暴露给全局
ep.fire(name + ".started");
}
@EL(name = "sys.stopping", async = true)
void stop() { if (repo != null) repo.close(); }
});
```
## 动态添加服务
```java
@EL(name = "sys.inited")
void sysInited() {
if (!app.attrs("redis").isEmpty()) { //根据配置是否有redis,创建redis客户端工具
app.addSource(new RedisClient())
}
}
```
## 系统心跳
> 需要用 [sched](https://gitee.com/xnat/sched) 添加 _sched.after_ 事件监听
```java
@EL(name = "sched.after")
void after(Duration duration, Runnable fn) {sched.after(duration, fn);}
```
> 每隔一段时间触发一次心跳, 1~4分钟(两个配置相加)随机心跳
> + 配置(sys.heartbeat.minInterval) 控制心跳最小时间间隔
> + 配置(sys.heartbeat.randomInterval) 控制心跳最大时间间隔
## 服务基础类: ServerTpl
> 推荐所有被加入到AppContext中的服务都是ServerTpl的子类
```java
app.addSource(new ServerTpl("服务名") {
@EL(name = "sys.starting", async = true)
void start() {
// 初始化服务
}
})
```
### bean注入:按类型匹配 @Inject
```java
app.addSource(new ServerTpl() {
@Inject Repo repo; //自动注入, 按类型
@EL(name = "sys.started", async = true)
void init() {
List