Beetl3.0 功能预览

Stella981
• 阅读 386

Beetl是一款全功能,性能优秀的国产模板引擎,可以广泛用于动态页面生成,静态页面生成,代码生成,文本转换,脚本和规则引擎等,从2011年来,一直维护,并得到国内用户的肯定。

1 性能篇

Beetl3.0 现在进展到M1版本,单元测试都通过,俩个模板类的性能测试也跑了一下,结果如下

国内Keb同学提供的性能测试来看 (https://gitee.com/xiandafu/teb) Beetl3.0 功能预览

老外提供的性能测试来看(https://github.com/mbosecke/template-benchmark) Beetl3.0 功能预览

注:Freemaker,Velocity,Thymleaf 都更新到最新版本了,Rocker是编译成class来执行模板

综合来说,整体性能仍然很优秀,这是Beetl一贯风格

2 功能篇

2.1 定界符增强

Beetl3 允许再定义一对“站位符和定界符”,比如定义了模板的定界符<%%>,站位符${},你可以定义一对,比如 和 #{} 如下是一段模板

select * from user_#{seq} where user_id=${userId}

如上SQL模板,可以对#{},和 ${}提供俩个解释,前者文本输出,后者输出"?"

再比如

<span>${seq}:#{text}</span>

可以对#{}自定义解释,增加XSS功能

2.2 片段渲染 增强

Beetl支持模板局部渲染,只要标记AJAX片段,Beetl可以只渲染这一部分,而忽略整体,这是和AJAX调用,取代了传统模板必须使用include来支持重用 3.0 增强了AJAX语法,是的AJAX标记的片段在使用的时候可以是一个独立模板,涉及的变量成为全局变量

@  var data=[1,3];
.......
@ #ajax sayHello:{
hello ${data[0]}
@}

渲染整体模板的时候,输出是hello,1,也可以专门渲染sayHello部分

Template t = gt.getAjaxTemplate("/ajax/ajax_template.html","sayHello");
t.binding("data",new int[]{1,3});
String str = t.render();

2.3 HTML 标签 增强

Beetl3.0 可以支持html标签,且支持绑定变量,比如

<cms:topic type="${xxx}" var="content,index">
${index}:${content}
</cms:topic>

topic 是一个自定义标签,java实现会导出俩个变量content,index供渲染标签体内用,新的3.0 支持导出的变量范围扩大到整个模板,使用export关键字比如

<cms:define export="contents"/>
//其他地方可以用conents
<cms:foreach list="${contents}" var="c">
<span>${c.title}</span>
</cms:foreach>

2.4 HTML 标签父子关系

这个JSP Tag 支持,Beetl2.X需要做些扩展,现在直接作为内置功能,因此,你可以用Beet的 html tag做出各种复杂的html扩展标签

2.5 语法糖

新增了 +=,-= 这种语法糖,比如

a+=3;
user.age+=1; 

2.6 提供语法树节点修改

2.X版本如果要修改语法树,写的代码较多,3.0能轻易的修改语法树,实现自己特有逻辑,比如在线内容管理系统要求编辑输入的循环不能循环超过1万次,

@ while(true){

@}

3.0能轻易修改while节点实现,通过GrammarCreator,替换自己的实现,从而限制while循环限制次数,Beetl的所有语法节点都可以被替换,以实现扩展需求,譬如 #{} 的实现需要xxs

    @Override
    public PlaceholderST createTextOutputSt2(Expression exp, FormatExpression format) {
        check("TextOutputSt2");
        return new YourXXSPlaceholderST(exp, format, null);
    }

YourXXSPlaceholderST 内部可以参考PlaceholderST.java实现,但增加了XSS校验

2.7 提升了脚本API

Beetl实质是脚本语言,因此GroupTemplate核心类新增script相关功能,提供了若干方便的API,你可以轻易使用Beetl实现规则引擎,脚本引擎,并能在性能上取得运算有势

Map ret = groupTemplate.runScript("return 2*利率;",paras);
Double d = ret.get("return");

2.8 采用ASM

Beetl2.x是用手写的字节码增强,当时Maven并不流行,所有的jar,都是以小为美,现在看来,已经没有必要了,所以Beetl3.x从新用ASM实现字节码增强,如一个User对象,会在运行时期生成一个辅助类

public class UserAccess extends AttributeAccess{
    public Object get(Object obj,String name){
        User user = (User)obj;
        int code = name.hashCode();
        switch(code)
        case 97:return user.getA();
        .....
    }
}

字节码增强 功能是可选的,默认还是采用反射方式实现属性调用

3 其他

Beetl3.X还有许多待完成的功能,比如编写分布式的模板加载器,可以用RedisResourceLoader或者MongoDBResourceLoader,会一直改进,敬请期待,也欢迎提出自己的想法。3.X让我有机会修复了1.x,2.x中的一些难以完善的功能,3.0修复的最早一个功能是在2015年提出来的,终于在3.0有机会改正了

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
2年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
Easter79 Easter79
2年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Stella981 Stella981
2年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这