AiFei知识图谱
杜福忠
2026-05-05
详解
详解
详解
Aifei.start(new AppConfig(), args);
项目main方法启动
commandLineArgumentToSystemProperty(args);
将来自 main 入口方法的命令行参数转换为系统属性,约定
参数以 "--" 打头。
如【java -jar app.jar --aifei.profiles.active=pro】会在
PropKit 中获取使用
PathUtil.init(aifeiConfig);
初始化整个 PathUtil,路径有:
static Path appHome;
static Path webRootPath;
static Path uploadPath;
static Path downloadPath;
static List<Path> classPathList;
aifeiConfig.config(settings);
系统配置
settings.setLogFactory
(不设置,有默认处理:slf4j > log4j2)
settings.setServer
配置 Server、Dispatcher、Handler
(本方法内容较多,下面开主题分支)
settings.configArgument
配置 Argument,定制 action 注入参数
(本方法内容较多,下面开主题分支)
settings.setProxyFactory
开启业务层 AOP。若不开启,则只注入原始对象而非 AOP 代理对象。
【JavassistProxyFactory、CglibProxyFactory】
settings.addGlobalInterceptor
添加全局拦截器
settings.setDownloadPath
配置文件下载路径,默认值为 "download"
settings.setUploadPath
配置文件上传路径,默认值为 "upload"
settings.setInjectSuperClass
配置超类是否注入,默认 false
aifeiConfig.config(routes);
路由
add(String path, Class<?> target)
手动添加路由。 应用场景:对性能有极致要求,
或者路由极少但 Class 文件却极多。
add(String path, Class<?> target, Interceptor... interceptors)
Routes 拦截器调用优先级高于全局拦截器。
scan(String basePackage)
扫描路由
scan(String basePackage, Interceptor... interceptors)
路由添加 Routes 级别拦截器
scan(String basePackage, Interceptor[] interceptors, Predicate<Class<?>> skip)
通过 skip 函数跳过指定 Class。
aifeiConfig.config(plugins);
interface Plugin
插件接口
void start();
void stop();
内置插件
AifeiDbPlugin
数据库操作
(本方法内容较多,下面开主题分支)
startPlugins(plugins);
启动 Plugin
aifeiConfig.onStart();
回调 onStart
Handler<I, O> handler = makeHandlerChain(settings.getHandlerList());
settings.getDispatcher().init(handler);
创建 Handler 链、初始化 Dispatcher
settings.getServer().start();
启动 Server
Runtime.getRuntime().addShutdownHook(new
Thread(Aifei::stop));
关闭 JVM:只支持 kill pid 不支持 kill -9 pid
必须配置
下页:嵌入式Server
Argument
AifeiDbPlugin
Aifei::stop()
关闭
settings.getServer().stop();
关闭 Server
aifeiConfig.onStop();
回调 onStop,仍可使用 plugin
stopPlugins(plugins);
关闭 Plugin
Handler<I, O> ret = handlerList.get(handlerList.size() - 1);
for (int i = handlerList.size() - 2; i >= 0; i--) {
Handler<I, O> current = handlerList.get(i);
current.next = ret;
ret = current;
}
return ret;
如有5个H:最终返回 H1,形成链:H1 → H2 → H3 → H4 → H5
调用
关系线
关系线
关系线
关系线
Server<P1, P2>
interface Server<P1, P2>
web服务接口定义
void
init
(Dispatcher<P1, P2, ?, ?> dispatcher);
初始化。至少需要持有下游 Dispatcher 对象
void start();
启动
void stop();
关闭
UndertowServer
AiFei内置的web服务
UndertowConfig
配置 默认取
undertow.txt
(配置规则同jfinal-undertow)
主要默认值:
port=80、host=0.0.0.0
config
(Consumer<UndertowConfig> configConsumer)
可代码进行配置:
new UndertowServer().config(uc -> {uc.setPort(8000);});
onStart(Consumer<Builder> onStartConsumer)
启动前回调
setUndertowHandler
(UndertowHandler undertowHandler)
定制 UndertowHandler 实现:init、handleRequest
与Servlet 过滤器功能类似:init、doFilter
有默认实现
UndertowHandler
请求入口 Undertow 的HttpHandler
连接下游 Aifei 的Dispatcher,
Dispatcher 进一步连接 Aifei 的Handler。
init(Dispatcher<HttpServerExchange, Void, ?, ?> dispatcher)
初始化 undertowHandler.init(dispatcher);
init
(Dispatcher<HttpServerExch
ange, Void, ?, ?> dispatcher)
设置Aifei的
Dispatcher
public synchronized void start()
启动
doStart()
启动项处理
printServerUrls();
控制台输出访问地址,
配置文件中可关闭:
undertow.printServerUrls=false
configConsumer.accept(config);
配置回调
configUndertow();
builder的各配置项:
https、IO 线程与 Worker 线程、Buffer、静态资源处理器
configHandler();
HttpHandler的配置:
Gzip、ServerName、Ssl、监听端口Host
onStartConsumer.accept(builder);
启动前回调
undertow = builder.build();
undertow.start();
Builder 构建 Undertow 对象并启动
public synchronized void stop()
关闭
undertow.stop();
handleRequest
(final HttpServerExchange
exchange)
Undertow的请求调用,
web系统的流量入口
处理静态资源:
if (path.indexOf('.') != -1)
resourceHandler.handleRequest(exchange);
一般:开发的时候才用到,上线后会有nginx进行代理
高效处理
处理动态资源:
dispatcher.dispatch(exchange, null);
转发到AiFei的Dispatcher,
(Dispatcher内容较多,下面开主题分支)
下页 Dispatcher调度器
SmartAifeiServer
计划
用国产项目smart 实现Aifei web服务,smart-aifei
(原因:学校的全国大学生创业大赛等信创项目更有吸引力)
Dispatcher
调度器
1: 引入 Dispatcher 对上游 Server 与下游 Handler 进行解耦。
2: Server 持有 Dispatcher,Dispatcher 持有 Handler。
3: Server 调用 Dispatcher.dispatch(...) 发送请求给 Dispatcher。
Dispatcher 调用 Handler.handle(...) 发送请求给 Handler。
4: 上游 Server 传递泛型参数 P1、P2 给 Dispatcher,
它将P1、P2 转化或封装成泛型参数 I、O 再传递给下游 Handler。
Server ---P1、P2---> Dispatcher ---I、O---> Handler
5: Dispatcher 将 Server 与 Handler 解耦之后,基于 aifei
开发的项目可以任意切换底层 Server 实现。例如切换
undertow、tomcat、netty。
interface Dispatcher
<P1, P2, I extends Input, O extends Output>
调度器代码 需要自己项目去实现,AiFei内核无该功能
(推荐加入Aifei官方的VIP获取aifei-vip-arch项目完整HIO实现)
(PS
:陕农大的实训学员使用aifei-dev-admin项目中smart-aifei已默认实现HIO
)
https://aifei.cn 是Aifei框架唯一官网。
https://aifei.dev 是“陕农大 信工分院 AI应用技术社团”发起的技术孵化社区,
免费提供域名+服务器 托管Aifei项目(含校外开源项目)。
void init
(Handler<I, O> handler);
初始化。至少需要持有下游 Handler 对象。
Aifei::start
调用settings.getDispatcher().
init
(handler);传参过来
void dispatch
(P1 p1, P2 p2);
接收 Server 请求,将 P1、P2 转化为 I、O 并调用 Handler.handle(...)
自定义示例:ExchangeDispatcher
基于UndertowServer实现一个简单调度器包装
public class ExchangeDispatcher implements Dispatcher<HttpServerExchange, Void, ExchangeInput, Output> {
private Handler<ExchangeInput, Output> handler;
@Override
public void init(Handler<ExchangeInput, Output> handler) {
this.handler = handler;
}
@Override
public void dispatch(HttpServerExchange exchange, Void unused) {
try {
handler.handle(exchange.getRequestPath(), new ExchangeInput(exchange), null);
} catch (Throwable e) {
exchange.endExchange();
}
}
}
代码:
public class
ExchangeInput
implements Input {
private final HttpServerExchange exchange;
public ExchangeInput(HttpServerExchange httpServerExchange) {
this.exchange = httpServerExchange;
}
public HttpServerExchange getExchange() {
return exchange;
}
... 其他接口实现方法 此处不用书写 IDEA可自动生成(主要是从exchange取值)
Aifei Handler
abstract class Handler<I extends Input, O extends Output>
抽象父类 H I O 模型
protected Handler<I, O> next;
下一个处理器(最后一个没有)
public abstract void handle(String path, I input, O output)
请求Server ---P1、P2---> Dispatcher ---I、O---> Handler调用到本方法
自定义示例:JsonHandler
基于前面自定义的ExchangeDispatcher实现一个简单Json返回值处理
示例
代码:
public class
JsonHandler
extends Handler<ExchangeInput, Output> {
@Override
public void handle(String path, ExchangeInput input, Output output) throws Throwable {
// 匹配路径获取 action
Action action = RouterKit.get().getRouter().getAction(path, input);
Class<?> targetClass = action.getTargetClass();
Object target = targetClass.newInstance();
Invocation invocation = new Invocation(action, target, input, output);
invocation.invoke();
//返回值
Object returnValue = invocation.getReturnValue();
HttpServerExchange exchange = input.getExchange();
OutputStream outputStream = exchange.getOutputStream();
exchange.getResponseHeaders().put(io.undertow.util.Headers.CONTENT_TYPE,
"application/json; charset=utf-8");
//写入Json字符串IO流
Json.of(returnValue).toJson(outputStream);
outputStream.close();
}
}
//仅实现核心原理,不做健壮判断等处理
//简单使用示例
public class DemoAppConfig implements AifeiConfig<ExchangeInput, Output> {
@Override
public void config(Settings<ExchangeInput, Output> settings) {
// 配置 Server、Dispatcher、Handler
settings.setServer(new UndertowServer(), new ExchangeDispatcher());
settings.addHandler(new JsonHandler());
}
@Override
public void config(Routes routes) {
routes.add("/", IndexService.class);
}
@Override
public void config(Plugins plugins) {
}
}
public static void main(String[] args) {
Aifei.start(new DemoAppConfig(), args);
}
Argument参数
待继续编写
以上内容仅代表作者本人观点,不代表亿图图示立场。
1
Aifei启动流程
2
嵌入式Server
3
Dispatcher调度器
4
Aifei Handler
5
Argument