利用FreeMarker生成java源代码

一 FreeMarker简介

Apache FreeMarker是一个Java模板引擎库,官网:http://freemarker.incubator.apache.org/

Apache FreeMarker is a template engine: a Java library to generate 
text output (HTML web pages, e-mails, configuration files, source 
code, etc.) based on templates and changing data. Templates are 
written in the FreeMarker Template Language (FTL), which is a simple, 
specialized language (not a full-blown programming language like PHP). 
You meant to prepare the data to display in a real programming 
language, like issue database queries and do business calculations, 
and then the template displays that already prepared data. In the 
template you are focusing on how to present the data, and outside the 
template you are focusing on what data to present.

这里写图片描述

This approach is often referred to as the MVC (Model View Controller) 
pattern, and is particularly popular for dynamic Web pages. It helps 
in separating the Web page designers (HTML authors) from the 
developers (Java programmers usually). Designers won’t face 
complicated logic in templates, and can change the appearance of a 
page without programmers having to change or recompile code.

While FreeMarker was originally created for generating HTML pages in 
MVC web application frameworks, it isn’t bound to servlets or HTML or 
anything Web-related. It’s used in non-web application environments as 
well.

模板就是把共性(固定不变的)的东西提取出来反复使用,节约时间 提高开发效率。现在主流的模板技术包括:FreeMarker和Velocity,模板技术推崇一种模式:输出=模板+数据。 
FreeMarker最开始被MVC Web框架用来生成HTML页面,但它的用途不仅限于HTML或者Web领域,比如本文所要介绍的生成JavaBean源代码。

二 生成JavaBean源代码

本文中将使用Freemarker 生成Person.java类代码,如下:

package com.ricky.java;

import java.util.List;

/**
 *  @author Ricky Fung
 */
public class Person {
    private Long id;
    private String name;
    private Integer age;
    private List<String> hobby;

    public void setId(Long id){
        this.id = id;
    }
    public Long getId(){
        return this.id;
    }

    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return this.name;
    }

    public void setAge(Integer age){
        this.age = age;
    }
    public Integer getAge(){
        return this.age;
    }

    public void setHobby(List<String> hobby){
        this.hobby = hobby;
    }
    public List<String> getHobby(){
        return this.hobby;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

2.1 引入Freemarker 依赖

<dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.23</version>
        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

2.2 Freemarker 模板文件 person.ftl

package ${packageName};

import java.util.List;

/**
 *  @author ${author}
 */
public class ${className} {
    <#list attrs as attr> 
    private ${attr.type} ${attr.name};
    </#list>

    <#list attrs as attr>
    public void set${attr.name?cap_first}(${attr.type} ${attr.name}){
        this.${attr.name} = ${attr.name};
    }
    public ${attr.type} get${attr.name?cap_first}(){
        return this.${attr.name};
    }

    </#list>
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

2.3 Create a configuration instance

Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
        cfg.setDirectoryForTemplateLoading(templateDir);    
        cfg.setDefaultEncoding("UTF-8");
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

2.4 Create a data-model 
1)In simple cases you can build data-models using java.lang and java.util classes and custom JavaBeans:

  • Use java.lang.String for strings.
  • Use java.lang.Number descents for numbers.
  • Use java.lang.Boolean for boolean values.
  • Use java.util.List or Java arrays for sequences.
  • Use java.util.Map for hashes.
  • Use your custom bean class for hashes where the items correspond to 
    the bean properties. For example the price property (getProperty()) 
    of product can be get as product.price. (The actions of the beans can 
    be exposed as well; see much later here)

2)代码构建数据模型

Map<String, Object> root = new HashMap<String, Object>();

        root.put("packageName", "com.ricky.java");
        root.put("className", "Person");
        root.put("author", "Ricky Fung");

        List<Attribute> attr_list = new ArrayList<Attribute>();
        attr_list.add(new Attribute("id", "Long"));
        attr_list.add(new Attribute("name", "String"));
        attr_list.add(new Attribute("age", "Integer"));
        attr_list.add(new Attribute("hobby", "List<String>"));

        root.put("attrs", attr_list);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

2.5 获取指定模板

Template temp = cfg.getTemplate("person.ftl");
  • 1
  • 1

此时,会在E:/Work/Freemarker/templates目录下查找person.ftl。

2.6 用数据渲染模板

Writer out = new OutputStreamWriter(System.out);
temp.process(root, out);
  • 1
  • 2
  • 1
  • 2

如果需要将结果序列化到硬盘上,可以使用下面代码:

File dir = new File("E:/Work/Freemarker/src/");
        if(!dir.exists()){
            dir.mkdirs();
        }
        OutputStream fos = new  FileOutputStream( new File(dir, "Person.java")); //java文件的生成目录   
        Writer out = new OutputStreamWriter(fos);
        temp.process(root, out);

        fos.flush();  
        fos.close();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

最后,贴上CodeGenerator.java完整的代码

package com.ricky.spring.springdemo.freemarker;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;

public class CodeGenerator {

    public static void main(String[] args) {

        try {
            new CodeGenerator().gen();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        }
    }

    public void gen() throws IOException, TemplateException{

        Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
        cfg.setDirectoryForTemplateLoading(new File("E:/Work/Freemarker/templates"));   
        cfg.setDefaultEncoding("UTF-8");
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);

        Template temp = cfg.getTemplate("person.ftl");  // load E:/Work/Freemarker/templates/person.ftl

        // Create the root hash
        Map<String, Object> root = new HashMap<String, Object>();

        root.put("packageName", "com.ricky.java");
        root.put("className", "Person");
        root.put("author", "Ricky Fung");

        List<Attribute> attr_list = new ArrayList<Attribute>();
        attr_list.add(new Attribute("id", "Long"));
        attr_list.add(new Attribute("name", "String"));
        attr_list.add(new Attribute("age", "Integer"));
        attr_list.add(new Attribute("hobby", "List<String>"));

        root.put("attrs", attr_list);

//      Writer out = new OutputStreamWriter(System.out);
//      Writer out = new OutputStreamWriter(System.out);
        File dir = new File("E:/Work/Freemarker/src/");
        if(!dir.exists()){
            dir.mkdirs();
        }
        OutputStream fos = new  FileOutputStream( new File(dir, "Person.java")); //java文件的生成目录   
        Writer out = new OutputStreamWriter(fos);
        temp.process(root, out);

        fos.flush();  
        fos.close();

        System.out.println("gen code success!");
    }
}




官网的一并拿来:URL:http://freemarker.org/


What is Apache FreeMarker?

Apache FreeMarker is a template engine: a Java library to generate text output (HTML web pages, e-mails, configuration files, source code, etc.) based on templates and changing data. Templates are written in the FreeMarker Template Language (FTL), which is a simple, specialized language (not a full-blown programming language like PHP). You meant to prepare the data to display in a real programming language, like issue database queries and do business calculations, and then the template displays that already prepared data. In the template you are focusing on how to present the data, and outside the template you are focusing on what data to present.

Figure

This approach is often referred to as the MVC (Model View Controller) pattern, and is particularly popular for dynamic web pages. It helps in separating web page designers (HTML authors) from developers (Java programmers usually). Designers won't face complicated logic in templates, and can change the appearance of a page without programmers having to change or recompile code.

While FreeMarker was originally created for generating HTML pages in MVC web application frameworks, it isn't bound to servlets or HTML or anything web-related. It's used in non-web application environments as well.

See the Manual for more details...

Disclaimer: Apache FreeMarker is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making process have stabilized in a manner consistent with other successful ASF projects. While incubation status is not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF.

Features

A few highlights of FreeMarker:

  • Powerful template language: Conditional blocks, iterations, assignments, string and arithmetic operations and formatting, macros and functions, including other templates, escaping by default (optional), and many more

  • Multipurpose and lightweight: Zero dependencies, any output format, can load templates from any place (pluggable), many configuration options

  • Internationalization/localization-aware: Locale sensitive number and date/time formatting, localized template variations.

  • XML processing capabilities: Drop XML DOM-s into the data-model and traverse them, or even process them declaratively

  • Versatile data-model: Java objects are exposed to the template as a tree of variables through pluggable adapters, which decides how the template sees them.

License

FreeMarker is Free software, licensed under the Apache License, Version 2.0. See the license here....

As of 2.3.24-pre01 (2015-09-02) the copyright owner in the license has changed to the Apache Software Foundation, as the project has started Apache Incubation (see disclaimer earlier).

部分转自:http://blog.csdn.net/top_code/article/details/50380825

猜你喜欢

转载自blog.csdn.net/ExceptionMapping/article/details/68066230