0 背景
近日公司开启了一个新项目,greenDao的引入和使用由我负责。由于之前没有使用过,同事在对象操作时把对象定义成了public属性,且没有get、set方法。当引入greenDao之后,可想而知,他写的模块全部飘红~~~。开始时候我们直接把greenDao生成的private属性改为public,暂时解决了问题,可是每次生成代码后都需要更改。在大神的点拨下,尝试着更改greenDao的生成模板。网上这方面的资料比较少,我把尝试过程跟大家分享下,如果那里说的不对或者有更改的方法还希望大家能指出。
1 自动生成探寻
上面说过开始时候我们都是手动将属性更改为public,再某次更改时候我随口问了下大神:greenDao有没有提供属性或者方法让自动生成的bean的属性为public。大神当时回答是不知道有还是没有,但是不到2分钟就就给我定位到了模板生成的地方。(这就是我和大神的区别啊,并非大神比我知道的更多,遇到的问题更多,而是在解决问题的层面上)
下面的代码为greenDao源码:
public DaoGenerator() throws IOException {
System.out.println("greenDAO Generator");
System.out.println("Copyright 2011-2015 Markus Junginger, greenrobot.de. Licensed under GPL V3.");
System.out.println("This program comes with ABSOLUTELY NO WARRANTY");
patternKeepIncludes = compilePattern("INCLUDES");
patternKeepFields = compilePattern("FIELDS");
patternKeepMethods = compilePattern("METHODS");
Configuration config = new Configuration(Configuration.VERSION_2_3_23);
config.setClassForTemplateLoading(this.getClass(), "/");
templateDao = config.getTemplate("dao.ftl");
templateDaoMaster = config.getTemplate("dao-master.ftl");
templateDaoSession = config.getTemplate("dao-session.ftl");
templateEntity = config.getTemplate("entity.ftl");
templateDaoUnitTest = config.getTemplate("dao-unit-test.ftl");
templateContentProvider = config.getTemplate("content-provider.ftl");
}
图中所标就是生产bean的模板,在那个文件中搜索private,很明显就是下图中指出的那一行。
2 更改模板
第一次尝试
找到那个模板后我肯定是要更改那个模板啊,可模板是在jar包里,我是直接在AndroidStudio的下载依赖库的文件夹下找到greendao-generator的jar包–>用rar打开编辑–>保存–>添加jar依赖,结果:失败!!!看来这样直接修改文件是不可以的,然后想把源码导入工程,更改模板后直接生成jar,不过一是觉得太麻烦,二是AndroidStudio导jar不会啊。会的朋友还望指教下。
第二次尝试
在我们写的greedao生成器的项目下添加模板,运用反射,将bean的生成模板改成我们自己的。
DaoGenerator daoGenerator = new DaoGenerator();
Configuration config = new Configuration(Configuration.VERSION_2_3_23);
config.setClassForTemplateLoading(daoGenerator.getClass(),"/");
Template templateEntity = config.getTemplate("entity_public.ftl");
Field templateEntityField = daoGenerator.getClass().getDeclaredField("templateEntity");
templateEntityField.setAccessible(true);
templateEntityField.set(daoGenerator, templateEntity);
daoGenerator.generateAll(schema, "../Project/app/src/main/java");
结果报了模板找不到的错误。模板和我的生产代码路径关系如下
第三次尝试
同样也是基于反射的,greenDao生成代码用的是一个叫freemarker的模板引擎,而它对加载模板提供了三种方式:
//基于类路径
public void setClassForTemplateLoading(Class clazz, String pathPrefix);
//基于文件系统
public void setDirectoryForTemplateLoading(File dir) throws IOException;
//基于Servlet Context
public void setServletContextForTemplateLoading(Object servletContext, String path);
关于freemarker的其他知识这里就不过多介绍了。
greenDao源码中用的是第一种,我这里尝试无果,所以想采用第二种。也就是模板在文件管理器中的绝对位置。直接使用了绝对定位试了下,类似于"D:\work…”,试验结果OK!还剩下一个小问题,就是多人开发模板的绝对路径肯定不一样,百度了下,提供了获取当期项目所在目录的方法,再兼容下Mac下的文件分隔符,所以我最终的代码为:
DaoGenerator daoGenerator = new DaoGenerator();
Configuration config = new Configuration(Configuration.VERSION_2_3_23);
config.setClassForTemplateLoading(daoGenerator.getClass(),"/");
config.setDirectoryForTemplateLoading(new File(System.getProperty("user.dir") + File.separator + "greendaogenerator" + File.separator + "src" + File.separator + "main" + File.separator + "java"));
Template templateEntity = config.getTemplate("entity_public.ftl");
Field templateEntityField = daoGenerator.getClass().getDeclaredField("templateEntity");
templateEntityField.setAccessible(true);
templateEntityField.set(daoGenerator, templateEntity);
daoGenerator.generateAll(schema, "../Project/app/src/main/java");
至此,更改greenDao生成模板介绍完毕,哪里说得不对或者还有其他更好的方案希望大家指出,谢谢!!!