2020-09-26 10:39

@李通 常规方法是通过 asm 或 cglib 做节码增强,其中 asm 方案可读性很差,而 cglib 增加了一个第三方依赖

jfinal 在 4.0 版本时去除了唯一的第三方依赖 cglib,采用了动态编译方案。该方案我从没在别的地方看到过,属于 jfinal 独创

不仅如此,该方案还与控制层的 AOP 使用了同一个 Interceptor + Invocation 结构,代码其实很优雅,注意看一下控制层的 AOP 没采用动态编译也没采用 cglib,而是采用的 actionKey 与 Action 映射的方式实现的

2020-09-26 01:03

@李通 这部分代码很少,主要流程就是:
1:ProxyGenerator 生成被代理类的子类,覆盖子类的被代理方法,生成的模板如下:
https://gitee.com/jfinal/jfinal/blob/master/src/main/java/com/jfinal/proxy/proxy_class_template.jf

看懂生成的 java 文件就能明白为啥可以实现 AOP 功能

2:生成 .java 文件以后,再使用 ProxyCompiler 编译成 .class 文件

3:使用 ProxyClassLoader 加载编译好的 .class 文件。使用 ProxyClassLoader 加载的类时,会用上其 AOP 相关功能

最好的办法是通过单步调试源码了解运行原理,代码不多,只有 600 多行,一会就看完了

2020-09-25 22:11

直接使用 Oss 的 API,本质上与 jfinal 无关

查看 Oss 的文档

2020-09-25 11:33

异常的源发地貌似不在 cglib,看一看源发地代码,解决问题

2020-09-25 10:58

@HAIV 理论上可以,但可能在 JSP 中无法使用 JSTL,原因未知

JSP 太古老了,非常不好用,不建议使用

2020-09-24 22:12

@jfinal爱好者22 导致的原因得面向 GSON 去了解,对于使用者来说 LinkedTreeMap 也是 Map 的一种实现,不影响使用

2020-09-24 22:10

博主的分析十分深入,值得学习

jfinal AOP 与 spring AOP 最大不同在于 jfinal 是极简设计,用户只需要学习三个核心概念:Interceptor、Before、Clear,这让学习成本低到极致

而 spring AOP 的概念一大堆,例如:Aspect、Advice、Joinpoint、Poincut、Introduction、Weaving、Around等等,并且需要引入IOC容器并配合大量的XML或者annotation来进行组件装配。概念太多让学习成本急剧上升,开发时头脑的负荷加重,认知成本很高,相应的开发效率也会降低


除了极简设计、学习成本低以外,jfinal AOP 的另一特色是采用动态编译方式实现 proxy, 在 java 界绝无仅有

同时还支持 cglib 进行增强模式实现,目的是为了支持 JRE 环境没有动态编译支持的场景

2020-09-24 18:00

undertow 不支持 jsp, 改用 jetty-server 就可以了:
https://jfinal.com/doc/1-6

@lyh061619 @天朝子民 这里使用的是 renderJsp(...) , 所以是明确了模板类型为 JSP 的, 这种情况无需配置 viewType, viewType 仅仅是针对 render(String) 方法,并不针对 renderXxx(...) 方法

2020-09-24 17:58

mysql 时间类型由 timestamp 改成 datetime

2020-09-24 17:57

这个应该是 GSON 自己的行为, 在 jfinal 内部是没能控制过的,找找 GSON 的文档,看有什么配置项可以使用

2020-09-24 17:56

@zzutligang 做一个 RedisKit 工具类,封装一下常用的一些 api,内部通过 jfinal 的 Redis 来获取需要的 jedis,实现所需功能:

public class RedisKit {
public void lpush(...) {
Jedis jedis = Redis.use().getJedis();
try {
jedis. lpush(...);
} finally {
jedis.close();
}
}
}

2020-09-24 15:06

确保序列化与反序列化算法一致

jfinal reids plugin 存数据前都会前数据进行序列化,默认使用 fst 序列化,那么你用别的工具拿数据时,也得用 fst 的算法反序列化

序列化以后的数据会多出一些表示数据本身特征的数据

通过 setSerializer(...) 可以配置自己的序列化算法

2020-09-23 17:23

@拿云 添加一个配置:
UndertowServer.create(MyApp.class)
.addHotSwapClassPrefix("cn.hinglo.activemq.plugin.")
.start();

文档中有说明:
https://jfinal.com/doc/1-5

2020-09-23 16:06

主动调用会更好,因为连接池会告诉数据库服务端客户端这边关闭掉了,否则服务端需要通过某种机制去关闭与客户端的连接,在此之前有一定的资源占用

2020-09-23 16:04

设计理念决定了用户体验