使用生成的Java源代码,例如
所有生成的类都是“值对象”类型,没有业务逻辑。如果我向生成的源代码添加方法,如果我重复生成源代码,我将松开这些方法。
这些Java代码生成工具是否提供了“扩展”生成代码的方法?
例如,
答案 0 :(得分:15)
对于JAXB,请参阅Adding Behaviours。
基本上,您将JAXB配置为返回您通常期望的对象的自定义实例。在下面的示例中,您将创建一个新对象PersonEx,它扩展了JAXB对象Person。这种机制非常有效,因为您从生成的类派生,而不是根本不改变JAXB类或模式。
package org.acme.foo.impl;
class PersonEx extends Person {
@Override
public void setName(String name) {
if(name.length()<3) throw new IllegalArgumentException();
super.setName(name);
}
}
@XmlRegistry
class ObjectFactoryEx extends ObjectFactory {
@Override
Person createPerson() {
return new PersonEx();
}
}
请注意,@ Override指令对于JAXB对象更改非常重要 - 它会阻止您的自定义变为孤立。
答案 1 :(得分:8)
对于Hibernate,您可以调整代码生成中使用的模板文件以更改其行为。如果您想调整可以编辑的HIbernate工具,例如: dao / daohome.ftl
您甚至可以在“toString()”输出中添加字段,编辑 .hbm.xml 文件
...
<property name="note" type="string">
<meta attribute="use-in-tostring">true</meta>
<column name="note" />
</property>
...
对于日志记录和验证,您可以考虑使用AOP with AspectJ(我不建议使用生成的代码,因为您可能需要多次从头开始构建代码)。
答案 2 :(得分:4)
首先,我要重申,生成代码的修改存在许多与之相关的问题,并且应尽可能避免。也就是说,有时这样做是不切实际的,可以避免或更多的努力,而不仅仅是在重新生成代码时处理更改。
遗憾的是,java不支持c#具有的部分类的概念。这些正是为了解决这类问题。
您应该看看您的代码生成工具是否支持某种形式的有意义的注释,这些注释会分隔您自己在类中添加的区域(如果您修改代码而不是添加代码,这种情况不太可能会有所帮助)
如果您真的希望这样做,最好的选择是最初生成文件,但立即将它们检入版本控制存储库。 然后进行更改,检查一下。
下次重新运行这些工具并让它们覆盖现有文件时,您可以对源控制的文件进行差异化并将更改合并(大多数琐碎的更改,例如添加新列/表将很费力。
如果代码生成器突然生成完全不同的代码(例如新版本),这对您没有多大帮助,但在这种情况下,您添加的任何代码不仅仅是依赖于已经公开公开的数据/方法的附加便利方法)无论如何融入课堂都会有问题。版本控制系统仍然有用,因为它还记录原始更改,这样您就可以看到之前添加的内容以及您需要重新创建新样式的内容。
答案 3 :(得分:3)
编辑生成的代码文件不是一个好主意,无论是通过自己编辑文件还是通过子类编辑。无论你做什么,一定要保持工具创建的签名不变,以便将来可以理解该文件是自动生成的。
我建议您研究工具的命令选项,看看它们是否允许您灵活使用。有些工具可以生成抽象类或接口而不是具体类。如果无法做到这一点,请创建一个包含自动生成对象作为成员变量的域对象。
答案 4 :(得分:3)
我使用Hibernate的方法是生成基类然后我扩展。我将所有业务逻辑(如果有的话)添加到这些子类中。我经常也最终更改Hibernate使用的FreeMarker模板,以进一步自定义生成的类。
答案 5 :(得分:1)
AOP引用是一个很好的引用。我将添加Spring,它内置了非常好的AOP功能。
答案 6 :(得分:1)