java模板类:用代码生成代码

尝尝用代码生成代码的元编程方式,写一个AI来编程把。

准备

1
2
3
4
5
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>

模板

新建一个以vm结尾的文件,里面放模板语法。

1
2
3
4
5
public class Person{
#foreach ($filed in $fields)
private String $filed;
#end
}

关于这个语法,参看:https://velocity.apache.org/engine/1.7/user-guide.html.

编程

进行动态注入数据,生成代码

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
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;

import java.io.*;
import java.util.Arrays;
import java.util.List;

public class TestTemplate {

public static void main(String[] args) throws IOException {
final VelocityEngine velocityEngine = new VelocityEngine();
velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
velocityEngine.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
velocityEngine.init();

final Template template = velocityEngine.getTemplate("template.vm");

// 准备点数据,可能从配置文件读取
List<String> fields = Arrays.asList("name", "age", "title", "content");

final VelocityContext context = new VelocityContext();
context.put("fields", fields);

final StringWriter writer = new StringWriter();
template.merge(context, writer);
System.out.println(writer.toString());

// 或者写入文件
Writer fileWriter = new PrintWriter(new File("Person.java"));
template.merge(context, fileWriter);
fileWriter.flush();
}
}

结果:

1
2
3
4
5
6
public class Person{
private String name;
private String age;
private String title;
private String content;
}