java自动生成service文件
本文使用freemarker模板技术,项目需要导入的jar文件:freemarker.jar
理解freemarker
FreeMarker是一种模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。
-
原理
-
java类设置需要的具体数据放入FreeMarker模板文件中,然后数据和模板进行动态绑定,通过调用FreeMarker模板文件解析类process()方法完成静态文件的生成。
-
作用
-
freemarker可用来避免重复造轮子,例如:service文件,我们都知道在java web中,创建一个实体bean,就需要有与之对应的service文件进行数据库相关操作。service文件里面的CURD操作都是类似的,只是文件里的bean名称不同,每次都手动创建开发效率根本上不去。
挖坑和填坑
首先:创建个.ftl后缀的模板文件,把静态文件内容粘贴进去
挖坑:把模板文件中的那些会变动的的字符串挖出来,用${data1}
表达式的写法代替,保留那些固定的字符串
填坑:在java方法中生成那些坑需要的动态数据,填入相应的${data1}
坑里
图解
template file模板文件 + java生成的数据 = 生成的静态文件
freemarker模板中如何获取值,参考freemarker表达式:http://blog.csdn.net/fhx007/article/details/7902040/
具体实现
工程目录:
DefaultTemplate.java文件,存放文件模板中所需的java动态数据。
public class DefaultTemplate {
private String packagePath; //当前包路径
private String baseDaoPath; //BaseDao接口路径
private String baseDaoImplPath; //BaseDao实现类路径
private String modelPath; //当前实体类路径
private String daoPath; //当前dao接口路径
private String servicePath; //当前service接口路径
private String as; //当前实体类第一个字符
private String tableName; //表名称
private String serviceName; //service名称
private String serviceImplName; //serviceImple名称
private String entityName; //当前实体类名称
private String entityViable; //实体变量
private String baseDaoName = "BaseDAO";//dao名称
private String baseDaoEntity = "baseDAO"; //dao实体
private String methodMapping; //requestMapping
private String description; //实体描述
private List<String> fieldlist;//实体字段列表
serviceImplTemplate.ftl模板文件,可以看到已经挖好了一个个坑,如${defaultTemplate.packagePath}用于和DefaultTemplate中的变量packagePath进行动态绑定
package ${defaultTemplate.packagePath};
import java.util.List;
import com.utils.Page;
import com.utils.Pageable;
import ${defaultTemplate.modelPath};
/**
*
* @version v1.0.0
* @since v1.0.0
* @date $date
*/
public interface ${defaultTemplate.serviceName}{
// 自动生成区域
/**
* 保存一条${defaultTemplate.entityName}
*
* @param ${defaultTemplate.entityViable}
*
* @return 返回${defaultTemplate.entityName}信息
*/
public void save(${defaultTemplate.entityName} ${defaultTemplate.entityViable});
config.properties配置文件,用于存放文件相应的路径以及变量
entityPath = src/com/module/exesceneandroid/bean
servicePath = src/com/module/exesceneandroid/service
serviceImplPath = src/com/module/exesceneandroid/service/impl
description = 描述
controllerPath = src/com/controller
portalPath = src/com/portal
daoPath = src/com/dao
serviceTemplatePath = src/com/core/gen/serviceTemplate.ftl
serviceImplTemplatePath = src/com/core/gen/serviceImplTemplate.ftl
entityTemplatePath = src/com/core/gen/entityTemplate.ftl
controllerTemplatePath = src/com/core/gen/controllerTemplate.ftl
portalTemplatePath = src/com/core/gen/portalTemplate.ftl
tempFtlPath = src/com/core/gen
TemplateGenerator中的init方法获取config.properties中的路径等一些变量信息
public void init() {
String propertyPath = "src/com/core/gen/config.properties"; // 使用默认路径
init(propertyPath);
}
public void init(String propertyPath) {
Map<String, String> properties = Property.getProperties(propertyPath);
entityPath = properties.get("entityPath");
daoPath = properties.get("daoPath");
servicePath = properties.get("servicePath");
serviceImplPath = properties.get("serviceImplPath");
controllerPath = properties.get("controllerPath");
portalPath = properties.get("portalPath");
entityTemplatePath = properties.get("entityTemplatePath");
serviceTemplatePath = properties.get("serviceTemplatePath");
serviceImplTemplatePath = properties.get("serviceImplTemplatePath");
controllerTemplatePath = properties.get("controllerTemplatePath");
portalTemplatePath = properties.get("portalTemplatePath");
description = properties.get("description");
tempFtlPath = properties.get("tempFtlPath");
}
Property中的getProperties方法具体实现怎么从.properties文件中获取变量
public static Map<String, String> getProperties(String fileName) {// 传入参数fileName是要读取的资源文件的文件名如(file.properties)
InputStream in = null;
Properties pros = new Properties();
File file = new File(fileName);
Map<String, String> map = new HashMap<String, String>();
try {
if (null != fileName) {
// 下面这种方式前提是资源文件必须类在同一个包下
in = new FileInputStream(file);
// 得到当前类的路径,并把资源文件名作为输入流
pros.load(in);
Enumeration<?> en = pros.propertyNames();// 得到资源文件中的所有key值
while (en.hasMoreElements()) {
String key = (String) en.nextElement();
map.put(key, pros.getProperty(key));
}
System.out.println("读取资源文件" + fileName + "成功!");
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("读取资源文件出错");
} finally {
try {
if (null != in) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("关闭流失败");
}
}
return map;
}
根据.ftl模板文件路径创建模板Template
Template template = new Configuration().getTemplate(serviceTemplatePath, "UTF-8");
具体数据经过一系列的转化,存放在defaultTemplate中,创建一个名为realFileName的文件用于存放动态绑定后的内容,通过process进行数据和模板的动态绑定。
Map<String, Object> rootMap = new HashMap<String, Object>();
rootMap.put("defaultTemplate", defaultTemplate);
try {
Writer out = new OutputStreamWriter(new FileOutputStream(realFileName), "UTF-8");
template.process(rootMap, out);
System.out.println(fileName + "生成成功");
} catch (Exception e) {
e.printStackTrace();
}
结语
本文展示了根据bean自动生成service的部分代码,impl、controller、portal controller自动生成的逻辑和service差不多。使用freemarker模板技术,省下了挺多功夫去创建文件、敲一些重复性的代码。