文档章节

freemarker源码解读之一--概述

黄亿华
 黄亿华
发布于 2013/09/11 22:51
字数 813
阅读 5135
收藏 47

最近在思考为如何xsoup添加自定义函数支持,基于这个目的,想起了最常用的模板引擎freemarker。于是down了源码下来,开始浏览一番。本文基于https://github.com/freemarker/freemarker上的2.3.20版本。

思考

看源码前,先思考一下,一个模板引擎,到底需要哪些东西?一门模板引擎其实是一个完整的语言,只不过它只具有单纯的输入/输出,不需要考虑其他的功能。

  • 语法解析,转换为AST(抽象语法树)

  • 语义分析,为AST附加上执行语义

  • 上下文环境的注入

  • 内置函数及外部函数支持

  • 其他外围机制(与框架/工具的集成等)

源码结构

打开freemarker的代码,core包里110个类一字排开,还有以下划线开头的“建议不要看”的类,看的人眼花缭乱啊!这一切都是因为Java规范的大师们,设计了一个“包级可见“的概念,大概就是,我写给自己用的代码,不要让你用!这一来,别人用是用不了了,好像看起来也变得很困难了…

还好现在的IDE都很强大,刷刷两下就给重构了,把一些类按照类型挪到多个包里,顿时清爽很多!可惜好多类/方法/字段都是包级可见,为了让这个重构版freemarker没那么多红叉,lz加了好几百个public,写到意识都模糊了…最后把自己的劳动成果共享出来吧:https://github.com/code4craft/freemarker-learning。主要是将freemarker.core包里内容拆开了,语法树相关的内容放到了freemarker.core.nodes包,异常放到了freemarker.core.exception包,一些模板内置功能放到了freemarker.core.buildin包,还有工具类放到了freemarker.core.util包。

顺便将freemarker的流程整理了一下:

流程

这是一个很经典的模板引擎的执行流程:

  • Configuration可以理解为一个工厂,它负责产生一个对外接口Template类。它首先会从cache中查找是否已经有编译好的Template,如果不存在,则对模板进行编译。
  • Template实际上是一个带执行语义的语法树,树的节点是TemplateObject。
  • FMParser是javacc生成的语法解析类,它最终输出是以FMParser.root()为根的语法树。
  • dataModel是外部对模板引擎的数据输入,它会被转化为TemplateModel,并代入模板的渲染过程。
  • 最后的步骤是根据数据,遍历编译好的语法树,并输出结果,这一步的入口时TemplateElement.accept()。

关于JavaCC

freemarker使用了JavaCC(Java Compiler Compiler)做parser。关于JavaCC,有一篇很好的入门帖,顺带复习一下编译原理:LL(0)文法,消除左递归等东西。http://cs.lmu.edu/~ray/notes/javacc/

JavaCC的下载在这里:http://javacc.java.net/,不知是我操作失误还是怎样,下载JavaCC-6.0之后,bin目录只有lib/javacc.jar文件。下载JavaCC-5.0src之后,才找到javacc脚本。难道就这么几百K的东西,还要搞增量更新?

总之下载成功之后,用javacc FTL.jj,即可生成一堆Parser文件。核心是FMParser,解析完的语法树在FMParser.root()里。

© 著作权归作者所有

黄亿华

黄亿华

粉丝 2448
博文 131
码字总数 116344
作品 7
程序员
私信 提问
加载中

评论(1)

gzh412163
gzh412163
1.没有二、三、四么…………

2.期待freemarker的更多文章~
细数FreeMarker的优缺点

一、 FreeMarker简介 FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出。 所谓模板,就是一份已经写好了基本内容,有着固定格式的文档,其中空出或者用占位符标识的内容...

oecp
2011/04/22
683
3
Struts2与Freemarker的配置方法(附源码和插件)

Freemarker是模板引擎,也可以说是一种表现层的框架,它有自己的模板指令,开发者如果不熟悉这些语法,很难进行表现层的开发。Struts2框架技术对Freemarker做了很好的支持,开发人员只要熟悉...

oecp
2011/04/28
451
0
FreeMarker 发布 Google AppEngine 的版本

来自 FreeMarker 在 Twitter 上的消息:FreeMarker 在上个月发布了一个新版本,该版本主要是提供了对 Google AppEngine 平台的支持。 下载 FreeMarker for GAE:freemarker-gae-pre3.jar Fre...

红薯
2010/07/04
2.8K
2
Jfinal中FreemarkerRender小改进

在与朋友讨论中,说到jf中的FreemarkerRender不能读到jar中的文件,查看jf源码是没有加入Freemarker的ClassTemplateLoder.读不到jar包中的静态文件,尝试着自己改进了下这个render。 把jfina...

kyle1970
2013/01/03
805
5
FreeMarker在eclipse中的入门例子

今天海浪为大家分享一个FreeMarker在eclipse中的入门例子。 一、在eclipse中创建FreeMarker模板 在FreeMarker中模板的概念就是:包含一些由${…}包围的特殊代码的文件。这些特殊代码是FreeM...

oecp
2011/04/26
923
0

没有更多内容

加载失败,请刷新页面

加载更多

开发中常用的正则表达式

为了能够更好地理解如何在C#环境中使用正则表达式,这里整理了一些常用的正则表达式: 罗马数字: string p1 = "^m*(d?c{0,3}|c[dm])" + "(l?x{0,3}|x[lc])(v?i{0,3}|i[vx])$";string t1 ......

木庄
38分钟前
4
0
【.NET程序打包】VS2019使用Installer Projects打包

C#—使用Installer Projects打包桌面应用程序 前言 打包桌面应用程序实在是一个不常使用的东西,偶尔使用起来经常会忘东忘西的耽误时间,因此,这篇文章多以图片记录过程,也是用于备忘。 下...

_Somuns
43分钟前
4
0
自定义注解,使用动态代理解决网站的字符集编码问题

第1章设置环境 安装操作系统,安装备份(镜像): JDK: 设置环境变量Eclipse:解压即可 Eclipse自身解压目录不包括中文 代码工作空间目录不包括中文Tomcat:解压不要包含中文目录M...

蓝来杯往
47分钟前
6
0
Solr中的字段类型field type

Solr含有多种字段类型,可用的字段类型基本都定义在了包org.apache.solr.schema中,列举如下: 类 说明 BinaryField 二进制数据 BoolField 布尔值,其中’t’/’T’/’1’都是true Collatio...

gantaos
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部