JFinal 3.3 发布,天下武功,唯快不破

多年前看过周星驰的电影《功夫》,里头的大 Boss 火云邪神有一句经典台词:天下武功,无坚不破,唯快不破。

周星驰最后通过变得比火云邪神更快,轻松击败火云邪神

在当时我对这句 “天下武功,无坚不破,唯快不破” 并不以为然,直到 2016 年,jfinal 社区有位小伙伴用 jfinal 做了一个电影网站《憨憨电影》,传送门 。看了里面的《闪电侠》这部美国科幻剧,传送门 ,才意识到唯快不破的深刻内涵,闪电侠本质就一个核心能力:“快”。运动速度可以自我调整到无比之快。就 “快” 这么一个特性,组合达成无数强大的功能。

例如,围绕飓风做反方向圆周运动,制造反作用力轻松化解飓风

例如,快速奔跑与空气摩擦制造闪电并发射出去,击败 Sand Demon

image

当然,还可以用“快”实现撩妹功能,撩到的还是美艳的女超人

一个 “快” 字,让原本棘手的问题得以巧妙化解,使得闪电侠战无不胜

科幻归科幻,回到现实中,那么到底这个 “唯快不破” 有没有没道理呢?在 jfinal 这些年的实战中被证实确有道理,例如 jfinal 在 6 年前率先使用 JFinal.start(…) 的方式秒起项目,不用配置 tomcat/jetty,修改源代码不用重启项目,本质就是 “快”,以至于几年以后发布的 spring boot 也用了这一招来启动项目

再例如 jfinal 完全消灭掉 xml 配置,独创 API 引导式配置,开发者在开发时除了不再被 xml 噪音干扰以外,还可以不用去记忆各种繁杂的配置,API 引导式配置不但可以利用 IDE 的代码提示而且还可以通过参数名、注释内容立即了解配置的含义。本质还是 “快”,以至于几年以后才发布的 spring boot 也去除 xml 并引入了与 jf API 引导式配置相似的设计 java config

再例如,jfinal 极大提升开发效率,往往在他人还在写配置文件的时候,jfinal 小伙伴们已然实现了功能产品可以快速上线,更早获取用户对产品的反馈,极大提升了产品迭代速度,这在如今分秒必争高速发展的互联网时代是创业成功的关键。如果产品的进化速度无比快,将是不可战胜的

以往 jfinal 的快,更多体现的是上手快、启动快、开发快、学习快、扩展快。那么这次 jfinal 3.3 关注一下运行起来的性能快不快? 以下是 jfinal 与 spring + mybatis 性能测试结果

jfinal 性能是 spring + mybatis 的 4.56 倍,这里是测试项目链接:https://gitee.com/jfinal/jfinal-performance

以下是 jfinal 模板引擎与 freemarker、velocity 性能测试结果

jfinal 模板引擎性能是 freemarker 的 4.27 倍,是 velocity 的 3.42,不仅速度快而且内存占用更小,这里是测试项目链接:https://gitee.com/jfinal/enjoy-performance

jfinal 3.3 对模板引擎做了十分细致的性能优化,性能大幅提升,jf 3.3 对模板引擎主要采用了如下优化方法:

  1. 采用 "笼罩" 式设计,引入 WriterBuffer 覆盖于入参 Writer、OutputStream 之上,使用内部的 byte[] buffer、char[] buffer、DateFormat 尽可能避免内存分配

  2. ExprList、StatList 避免在单一内部对象时 for 循环

  3. 添加 byte 模式,使得模板静态内容只 encode 一次

  4. fnv 64 算法代替 StingBuider 拼接字符串生成 hash

  5. 优化 Integer、Double、Float、Boolean 等类型数据输出

  6. 优化日期类型格式化,回收利用 SimpleDataFormat

除了模板引擎性能上的大幅提升以外,jfinal 3.3 还进行了将近 50 项增强与改进

1:模板引擎添加 byte 输出模式

template.render(data, request.getOutputStream());

该模式最大的好处是,在 web 环境下直接输出 byte 流,避免对模板文件中的静态文本部分做 encode 操作,性能可提升一到两倍

2:添加 ControllerFactory,支持用户接管 controller 生命周期

me.setControllerFactory(new FastControllerFactory());

不仅可以控制 controller 生命周期、重复回收利用 controller 对象,还可以方便进行 IOC、DI 动作

3:增强 PropKit、Prop,添加 append 系列方法

PropKit.use("dev.txt").append("prod.txt");

大多数情况下开发环境与生产环境配置文件的配置项都相同,引入 append 方法,可以让 prod.txt 配置文件中仅添加与 dev.txt 中不同的配置项,例如 password,极大减少配置工作量,也减少了出错的可能性,感谢 @t-io 作者提出的好建议

4:添加 #number 指令,支持格式化输出数值数据

#number(3.1415926, "#.##")
#number(0.9518, "#.##%")
#number(300000, "光速为每秒 ,### 公里。")

5:Model、BaseModel、MappingKit 改由模板引擎实现

public class #(mappingKitClassName) 
 public static void mapping(ActiveRecordPlugin arp) 
  #for (tableMeta : tableMetas)
   arp.addMapping("#(tableMeta.name)", "#(tableMeta.primaryKey)", #(tableMeta.modelName).class);
  #end
 
}

由字符串拼接改由模板引擎实现以后,不仅便于可读性与维护性,而且十分有利于自由定制个性化模板

6:支持自定义 ActionHandler,彻底接管 action 请求

me.setActionHandler(new MyActionHandler());

7:Controller.renderToString(…) 支持 viewPath

renderToString("reply_item.html");

老版本中要使用全路径,新版本更省代码,viewPath 规则与其它 render 方法完全一致,不增加学习成本,全路径使用方式也天然兼容。

jfinal 3.3 版本如上的增强与改进还有很多,为限制篇幅,在此不在赘述,后续会单独补充详细的 jfinal-3.3-changelog.txt

ONE MORE THING:俱乐部将直播 jfinal 3.3 的各种性能优化技术,优化所使用的工具、优化的方法与过程,对此感兴趣的同学可加入俱乐部:http://jfinal.com/club

See original: 

JFinal 3.3 发布,天下武功,唯快不破