低代码探索:Java模板引擎技术

简介: 本篇将探索代码生成技术。因为业务开发中使用Java语言较多,所以这里以Java作为背景语言。

系列文章:

Mavan:自定义骨架及工程初始化

一 前言

   上一篇文章简单介绍了工程的初始化方法,本篇将探索代码生成技术。因为业务开发中使用Java语言较多,所以这里以Java作为背景语言。

   大家熟知并且日常都在使用Spring/SpringMVC/SpringBoot、Mybatis框架,在开发中我们经常需要手写Entity、Mapper、dao、service、controller相关代码,这些重复性的工作会占用很多工作时间。如果有一个代码生成工具来做这些重复工作,显然可以提高我们的工作效率。这时,就需要了解模板引擎技术。

二 模板引擎工具:freemarker与velocity

   最早接触的是velocity,记得14,15年左右,当时在某家公司开发的前端页面,就是使用velocity作为模板引擎。创建前端页面的vm/tpl模板后,利用velocity提供的能力,编写脚本生成静态页面,然后再走上线更新。

   除了velocity之外,freemarker也是一款模板引擎,使用FreeMarker Template Language(FTL)编写,它是一种简单的、专用的语言。

   关于二者(有时也会包括thymeleaf)的对比,已经有一些文章进行了分析,这里不再赘述,感兴趣的朋友可以搜索,或在评论中留言一起探讨。这里基于以前的一些调研工作,选择freemarker作为这里使用的模板引擎,用于示例。

三 freemarker介绍

   freemarker的基础介绍,可以参考freemarker在线手册,中文版地址:http://freemarker.foofun.cn/

简单来说,FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

   freemarker的几个关键概念:模板(template)、Java对象(Java Object)、输出(Output),三者含义和关系可通过下图体现:

(1)其中,template是我们要使用的模板,基于这个模板来生成文件。简单来说,就是一些固定模式(代码/标签/逻辑)+变量的组合,其中变量在后面根据需要,替换成所需的值;

(2)Java Object是模型/对象,可以简单理解为一些key-value对,key是变量名称,value就是变量的值;

(3)Output是输出结果,在把template中的变量替换成object中的value后,就得到了我们预期的文件。

而替换的动作,就是由freemarker来实现的。

四 示例

4.1 工程结构

   这里采用maven工程,idea创建,工程目录结构如下:

4.2 依赖包引入-pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>template-engine</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.23</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
        <finalName>${project.artifactId}</finalName>
    </build>
</project>

4.3 自定义freemark模板

   这里预期是生成一个Java类,如下所示,是一个典型的bean,包括几个属性和对应的get/set方法,几个变量: packageName-包名,className-类名,属性:id, userName, password

package ${packageName};
public class ${className} {
    private Integer ${id};
    private String ${userName};
    private String ${password};
    public Integer get${id?cap_first}(){
        return ${id};
    }
    public void set${id?cap_first}(Integer ${id}){
        this.${id}=${id};
    }
    public String get${userName?cap_first}(){
        return ${userName};
    }
    public void set${userName?cap_first}(String ${userName}){
        this.${userName}=${userName};
    }
    public String get${password?cap_first}(){
        return ${password};
    }
    public void set${password?cap_first}(String ${password}){
        this.${password}=${password};
    }
}

4.4 定义生成代码方法

package com.freemark.demo.templates.util;
import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
public class FreemarkTest {
  private static final String TEMPLATE_PATH = "src/main/java/com/freemark/demo/templates";
  private static final String CLASS_PATH = "src/main/java/com/freemark/demo";
  public static void main(String[] args) {
    // 创建freeMarker配置实例
    Configuration configuration = new Configuration();
    Writer out = null;
    try {
      // 设置模版路径
      configuration.setDirectoryForTemplateLoading(new File(TEMPLATE_PATH));
      // 创建数据模型
      Map<String, Object> dataMap = new HashMap<>();
      dataMap.put("packageName", "com.freemark.demo");
      dataMap.put("className", "Test");
      dataMap.put("id", "id");
      dataMap.put("userName", "userName");
      dataMap.put("password","password");
      // 加载模版文件
      Template template = configuration.getTemplate("test.ftl");
      // 生成文件流
      File docFile = new File(CLASS_PATH + "/" + "Test.java");
      out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));
      // 输出到文件
      template.process(dataMap, out);
      System.out.println("Test.java 源码生成成功!");
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        if (null != out) {
          out.flush();
        }
      } catch (Exception e2) {
        e2.printStackTrace();
      }
    }
  }
}

我们运行main方法,可以看到控制台会打印出 Test.java 源码生成成功! 并在src/main 指定的包下,生成了Test.java类文件,内容如下:

package com.freemark.demo;
public class Test {
    private Integer id;
    private String userName;
    private String password;
    public Integer getId(){
        return id;
    }
    public void setId(Integer id){
        this.id=id;
    }
    public String getUserName(){
        return userName;
    }
    public void setUserName(String userName){
        this.userName=userName;
    }
    public String getPassword(){
        return password;
    }
    public void setPassword(String password){
        this.password=password;
    }
}
相关文章
|
9天前
|
监控 Java 物联网
Java串口通信技术探究1:深入理解RXTX库
Java串口通信技术探究1:深入理解RXTX库
24 2
|
3天前
|
Kubernetes Java 调度
Java容器技术:Docker与Kubernetes
Java容器技术:Docker与Kubernetes
13 0
|
3天前
|
存储 安全 Java
深入理解Java字节码与反编译技术
深入理解Java字节码与反编译技术
11 0
|
3天前
|
监控 Java Maven
揭秘Java Agent技术:解锁Java工具开发的新境界
作为JDK提供的关键机制,Java Agent技术不仅为Java工具的开发者提供了一个强大的框架,还为性能监控、故障诊断和动态代码修改等领域带来了革命性的变革。本文旨在全面解析Java Agent技术的应用场景以及实现方式,特别是静态加载模式和动态加载模式这两种关键模式。
22 0
|
9天前
|
存储 缓存 前端开发
Java串口通信技术探究3:RXTX库线程 优化系统性能的SerialPortEventListener类
Java串口通信技术探究3:RXTX库线程 优化系统性能的SerialPortEventListener类
33 3
|
9天前
|
安全 IDE Java
Java串口通信技术探究2:RXTX库单例测试及应用
Java串口通信技术探究2:RXTX库单例测试及应用
25 4
|
9天前
|
存储 前端开发 安全
13:会话跟踪技术Session的深度应用与实践-Java Web
13:会话跟踪技术Session的深度应用与实践-Java Web
24 3
|
9天前
|
存储 前端开发 搜索推荐
12:会话跟踪技术Cookie的深度应用与实践-Java Web
12:会话跟踪技术Cookie的深度应用与实践-Java Web
23 4
|
11天前
|
供应链 Java API
Java 8新特性解析及应用区块链技术在供应链管理中的应用与挑战
【4月更文挑战第30天】本文将深入探讨Java 8的新特性,包括Lambda表达式、Stream API和Optional类等。通过对这些新特性的详细解析和应用实例,帮助读者更好地理解和掌握Java 8的新技术。
|
11天前
|
存储 安全 Java
【亮剑】`ConcurrentHashMap`是Java中线程安全的哈希表,采用锁定分离技术提高并发性能
【4月更文挑战第30天】`ConcurrentHashMap`是Java中线程安全的哈希表,采用锁定分离技术提高并发性能。数据被分割成多个Segment,每个拥有独立锁,允许多线程并发访问不同Segment。当写操作发生时,计算键的哈希值定位Segment并获取其锁;读操作通常无需锁定。内部会根据负载动态调整Segment,减少锁竞争。虽然使用不公平锁,但Java 8及以上版本提供了公平锁选项。理解其工作原理对开发高性能并发应用至关重要。