原来这就是Java代码生成器的原理啊,太简单了
1. 前言
2. 代码生成器的使用场景
3. 代码生成器的制作流程
4. 代码生成器演示
4.1 模板制作
4.2 生成器编写
5. 总结
Last updated
Last updated
${true ? 'checked': ''}<#list fields as field>
private ${field.fieldType} ${field.fieldName};
</#list><dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>public class JavaProperties {
// 包名
private final String pkg;
// 类名
private final String entityName;
// 属性集合 需要改写 equals hash 保证名字可不重复 类型可重复
private final Set<Field> fields = new LinkedHashSet<>();
// 导入类的不重复集合
private final Set<String> imports = new LinkedHashSet<>();
public JavaProperties(String entityName, String pkg) {
this.entityName = entityName;
this.pkg = pkg;
}
public void addField(Class<?> type, String fieldName) {
// 处理 java.lang
final String pattern = "java.lang";
String fieldType = type.getName();
if (!fieldType.startsWith(pattern)) {
// 处理导包
imports.add(fieldType);
}
Field field = new Field();
// 处理成员属性的格式
int i = fieldType.lastIndexOf(".");
field.setFieldType(fieldType.substring(i + 1));
field.setFieldName(fieldName);
fields.add(field);
}
public String getPkg() {
return pkg;
}
public String getEntityName() {
return entityName;
}
public Set<Field> getFields() {
return fields;
}
public Set<String> getImports() {
return imports;
}
/**
* 成员属性封装对象.
*/
public static class Field {
// 成员属性类型
private String fieldType;
// 成员属性名称
private String fieldName;
public String getFieldType() {
return fieldType;
}
public void setFieldType(String fieldType) {
this.fieldType = fieldType;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
/**
* 一个类的成员属性 一个名称只能出现一次
* 我们可以通过覆写equals hash 方法 然后放入Set
*
* @param o 另一个成员属性
* @return 比较结果
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Field field = (Field) o;
return Objects.equals(fieldName, field.fieldName);
}
@Override
public int hashCode() {
return Objects.hash(fieldType, fieldName);
}
}
}package ${pkg};
<#list imports as impt>
import ${impt};
</#list>
/**
* the ${entityName} type
* @author felord.cn
*/
public class ${entityName} {
<#list fields as field>
private ${field.fieldType} ${field.fieldName};
</#list>
}/**
* 简单的代码生成器.
*
* @param rootPath maven 的 java 目录
* @param templatePath 模板存放的文件夹
* @param templateName 模板的名称
* @param javaProperties 需要渲染对象的封装
* @throws IOException the io exception
* @throws TemplateException the template exception
*/
public static void autoCodingJavaEntity(String rootPath,
String templatePath,
String templateName,
JavaProperties javaProperties) throws IOException, TemplateException {
// freemarker 配置
Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
configuration.setDefaultEncoding("UTF-8");
// 指定模板的路径
configuration.setDirectoryForTemplateLoading(new File(templatePath));
// 根据模板名称获取路径下的模板
Template template = configuration.getTemplate(templateName);
// 处理路径问题
final String ext = ".java";
String javaName = javaProperties.getEntityName().concat(ext);
String packageName = javaProperties.getPkg();
String out = rootPath.concat(Stream.of(packageName.split("\\."))
.collect(Collectors.joining("/", "/", "/" + javaName)));
// 定义一个输出流来导出代码文件
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(out));
// freemarker 引擎将动态数据绑定的模板并导出为文件
template.process(javaProperties, outputStreamWriter);
}// 路径根据自己项目的特点调整
String rootPath = "C:\\Users\\felord\\IdeaProjects\\codegenerator\\src\\main\\java";
String packageName = "cn.felord.code";
String templatePath = "C:\\Users\\felord\\IdeaProjects\\codegenerator\\src\\main\\resources\\templates";
String templateName = "entity.ftl";
JavaProperties userEntity = new JavaProperties("UserEntity", packageName);
userEntity.addField(String.class, "username");
userEntity.addField(LocalDate.class, "birthday");
userEntity.addField(LocalDateTime.class, "addTime");
userEntity.addField(Integer.class, "gender");
userEntity.addField(Integer.class, "age");
autoCodingJavaEntity(rootPath, templatePath, templateName, userEntity);