`
bloodwolf_china
  • 浏览: 131082 次
社区版块
存档分类
最新评论

groovy 模板引擎实现原理分析

阅读更多
groovy的SimpleTemplateEngine实现了模板功能,类似于jsp。那就分析groovy是如何实现模板的。

使用模板
Template template = new SimpleTemplateEngine().createTemplate(
        new StringReader("<% // This is a comment that will be filtered from output %>\n" +
        "Hello <%out.println(name);%> !")
    );

    final StringWriter sw = new StringWriter();
    template.make([name:'bloodwolf_china').writeTo(sw);
    println sw.toString();


看看SimpleTemplateEngine类
public Template createTemplate(Reader reader) throws CompilationFailedException, IOException {
        SimpleTemplate template = new SimpleTemplate();
        String script = template.parse(reader);
              
            template.script = groovyShell.parse(script, "SimpleTemplateScript" + counter++ + ".groovy");
       
        return template;
    }


这儿做了三件事
1、创建了一个SimpleTemplate对象
2、解析模板,主要是把<%=exp%>转为groovy的内置表达式${exp},把非<%code%>转为调用out.print(内容)函数,<%code%>中的就是groovy代码了。这样就把整个模板解析为一段代码。如
引用
Hello <%out.println(name);%> !
变成
out.print("Hello ");
out.println(name);
out.print(" !");

3、用groovyShell获取一个Script对象

Script对象只一个支持普通groovy对象,利用了Groovy的特性
实现 getProperty(String property)方法,从参数绑定对象中获取属性,这样脚本中就能获取绑定参数。
public abstract class Script extends GroovyObjectSupport {
    private Binding binding;
    public Object getProperty(String property) {
        try {
            return binding.getVariable(property);
        } catch (MissingPropertyException e) {
            return super.getProperty(property);
        }
    }
     public abstract Object run();
}

groovyShell把一段代码组装成一个GroovyCodeSource对象,然后调用GroovyClassLoader,CompilationUnit把CodeSource编译成一个Script对象,run()方法中执行的即是out.print(模板内容)这段代码。

在看看如何输出模板内容的
private static class SimpleTemplate implements Template {

        protected Script script;

        public Writable make() {
            return make(null);
        }

        public Writable make(final Map map) {
            return new Writable() {
                /**
                 * Write the template document with the set binding applied to the writer.
                 *
                 * @see groovy.lang.Writable#writeTo(java.io.Writer)
                 */
                public Writer writeTo(Writer writer) {
                    Binding binding;
                    if (map == null)
                        binding = new Binding();
                    else
                        binding = new Binding(map);
                    Script scriptObject = InvokerHelper.createScript(script.getClass(), binding);
                    PrintWriter pw = new PrintWriter(writer);
                    scriptObject.setProperty("out", pw);
                    scriptObject.run();
                    pw.flush();
                    return writer;
                }

                /**
                 * Convert the template and binding into a result String.
                 *
                 * @see java.lang.Object#toString()
                 */
                public String toString() {
                    StringWriter sw = new StringWriter();
                    writeTo(sw);
                    return sw.toString();
                }
            };
        }
}

很清楚了,调用make方法,创建一个Script对象,绑定参数binding = new Binding(map)。
创建一个PrintWriter,绑定为out参数,而模板解析的代码中的out.print(内容)就有着落了。

所以:
  • Groovy的模板是通过编译,生成Java类,然后调用方法实现的
  • 使用模板机制注意要缓存Script对象或Template对象,否则每次调用都会编译生成一个新的Java类,导致内存溢出/泄露
1
0
分享到:
评论

相关推荐

    grails脚手架2次优化

    Grails的脚手架基于GORM(Grails Object Relational Mapping)和Groovy模板引擎,通过解析Domain Class自动构建出Controller、View以及相应的模板文件。在运行时,这些文件负责处理数据的增删改查操作。了解这一工作...

    Grails in Action

    - **Views**:展示数据给用户,通常使用模板引擎(如GSP)来渲染HTML页面。 - **Services**:封装复杂的业务逻辑,避免控制器过于臃肿。 - **Interceptors**:提供AOP(面向切面编程)的能力,可以用来实现诸如权限...

    生成hibernate配置文件和xml的辅助类generate

    例如,它可能使用了Java的反射API来分析实体类,或者使用模板引擎(如FreeMarker、Velocity)生成XML文件。 “工具”标签表明这是一个实用工具,可以集成到开发环境或构建流程中,自动化处理配置任务。 虽然没有...

    my-site-master_springboot_

    通过学习和分析 "my-site-master_springboot_" 项目,你可以深入了解 Spring Boot 如何启动、如何配置,以及如何与各种组件(如数据库、模板引擎、安全框架等)协同工作。对于初学者来说,这是一个非常有价值的实战...

    SpringBoot 源码解析——源码模块功能分析.docx

    * spring-boot-starter-groovy-templates:提供了对 Groovy 模板引擎的支持。 * spring-boot-starter-hateoas:提供了对 HATEOAS RESTful API 的支持。 * spring-boot-starter-integration:提供了对集成测试的支持...

    SpringBoot启动器Starters使用及原理解析

    * spring-boot-starter-groovy-templates:支持Groovy模板引擎。 * spring-boot-starter-hateoas:通过spring-hateoas支持基于HATEOAS的RESTful Web服务。 * spring-boot-starter-hornetq:通过HornetQ支持JMS。 * ...

    srping4.1.6核心包_spring4.1.6_源码.zip

    4. **Web MVC改进**:Spring MVC在4.1.6中增强了模型视图解析,支持更多模板引擎,如FreeMarker和Thymeleaf,并且改进了异常处理。 5. **WebSocket支持**:加强了对WebSocket协议的支持,提供了STOMP子协议的集成,...

    《Grails权威指南》中的bookmarks工程代码

    - 视图负责渲染HTML页面,通常与模板引擎Thymeleaf或GSP(Groovy Server Pages)配合使用。 - 配置文件如`grails-app/conf/Config.groovy`用于设置应用的全局属性和环境变量。 3. **GORM详解**: - GORM提供了...

    JavaOpenFramework.rar_JavaOpenFramework_java 框架

    它支持TDD(Test-Driven Development)和敏捷开发,提供了一个简洁的API和强大的模板引擎。 5. **Apache Maven**:虽然Maven不是一个应用框架,但它是一个项目管理和综合工具,用于构建、依赖管理和文档生成。许多...

    SoapUI4.0源码全

    源码中包含了脚本引擎的实现,对于想要利用脚本增强测试逻辑的人来说是一大宝藏。 10. **数据驱动测试**:通过数据驱动测试,你可以使用外部数据源来驱动测试用例。源码中这部分的实现可以帮助你理解如何实现数据...

    Spring 学习笔记《Spring Boot》源码

    JSP(JavaServer Pages)是一种用于动态创建网页的技术,Spring Boot 支持在某些特定环境下使用 JSP,尽管它更倾向于推荐使用Thymeleaf、Freemarker或Mustache等模板引擎。 源码分析可以从以下几个方面展开: 1. *...

    Mybatis generator 使用

    对于源码分析,Mybatis Generator 的实现原理主要依赖于 JDBC API 来获取数据库的元数据信息,然后根据这些信息动态生成 Java 源代码。它使用了 Velocity 模板引擎来生成 Java 代码,通过模板定义了不同类型的代码...

    JAVA上百实例源码以及开源项目源代码

    Java实现的FTP连接与数据浏览程序 1个目标文件 摘要:Java源码,网络相关,FTP Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。 部分源代码摘录: ftpClient = new FtpClient(); //实例化FtpClient对象 ...

    Java进阶路线

    - **FreeMaker/Velocity/JSP**:常用的模板引擎。 - **JSF, JSTL, Tag**:Java Server Faces 和 JSP 标签库。 - **Spring, Struts, JSF**:流行的Web开发框架。 - **Nginx, Apache, Tomcat, JBoss, Jetty**:常用的...

    Grails 1.1 Web Application Development

    - **视图(View)**:展示数据给用户,通常使用FreeMarker或Velocity模板引擎。 - **服务(Service)**:封装业务逻辑,可以被多个控制器共享使用。 - **拦截器(Interceptor)**:执行跨越多个控制器和动作的代码,如认证...

    Pro Spring3

    - **代码分析**:深入分析示例代码,理解各组件间的交互机制。 - **部署与测试**:指导如何部署该应用并进行基本的功能测试。 #### 四、Spring 中的依赖注入(第4章) - **依赖注入概念**:解释依赖注入...

    59-数栖-实时开发v1.4.0-用户手册.pdf

    实时开发是数栖平台中实现数据资产化的关键组件之一,有助于企业快速响应业务需求变化,及时处理原始数据并进行实时分析计算,最终将处理后的数据存储至诸如Oracle、Elasticsearch、HBase等数据库中,以便后续查询或...

    Spring Webscripts Reference Documentation

    作为开源项目,Spring Webscripts的源码是公开的,开发者可以直接查看并理解其内部工作原理。对于想要深入研究或定制功能的开发者来说,源码阅读是很好的学习途径。此外,Spring提供的各种工具,如Spring Tool Suite...

Global site tag (gtag.js) - Google Analytics