如何扩展JAXB,CXF或Hibernate工具生成的Java代码?

用生成的Java源代码,比如

  • 用Hibernate工具生成的代码
  • 使用JAXB模式绑定生成的代码(xjc)
  • 用WDSL2Java生成的代码(cxf)

所有生成的类都是“值对象”类型,没有业务逻辑。 如果我向生成的源代码添加方法,如果我重复生成源代码,我将松开这些方法。

这些Java代码生成工具是否提供了“扩展”生成代码的方法?

例如,

  • 覆盖ToString方法(用于记录)
  • 实现访问者模式(用于数据分析/validation)

对于JAXB,请参阅添加行为 。

基本上,您将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对象更改很重要 - 它会阻止您的自定义变为孤立

至于Hibernate,您可以调整代码生成中使用的模板文件来改变它们的行为。 如果你想调整你可以编辑的HIbernate工具,例如: dao / daohome.ftl

您甚至可以在编辑.hbm.xml文件的“toString()”输出中添加字段

 ...  true   ... 

对于日志记录和validation,您可以考虑将AOP与AspectJ一起使用(我不建议使用生成的代码,因为您可能需要多次从头开始构建)。

首先,我要重申,对生成的代码的修改存在许多与之相关的问题,并且应尽可能避免。 也就是说,有时候这样做是不切实际的,可以避免或更多的努力,而不仅仅是在重新生成代码时处理更改。

遗憾的是,java不支持c#具有的部分类的概念。 这些正是为了解决这类问题。

你应该看看你的代码生成工具是否支持某种forms的有意义的注释,这些注释分隔了你自己在类中添加的区域(这不太可能,如果你修改代码而不是添加它就无济于事)

如果您真的希望这样做,最好的选择是最初生成文件,但立即将它们检入版本控制存储库。 然后进行更改,检查一下。

下次重新运行这些工具并让它们覆盖现有文件时,您可以对源控制的文件进行区分并将更改合并(大多数琐碎的更改,例如添加新列/表将是很少的努力。

如果代码生成器突然生成完全不同的代码(例如新版本),这对你没有多大帮助,但在这种情况下,你添加的任何代码不仅仅是依赖于已公开公开的数据/方法的附加便利方法)也会遇到问题无论如何融入课堂。 然而,版本控制系统仍然有用,因为它还记录了原始更改,因此您可以看到之前添加的内容以及您需要在新样式中重新创建的内容。

编辑生成的代码文件不是一个好主意,无论是通过自己编辑文件还是通过子类编辑。 无论你做什么,一定要保持工具创建的签名不变,以便将来可以理解该文件是自动生成的。

我建议您研究工具的命令选项,看看它们是否允许您灵活使用。 有些工具可以生成抽象类或接口而不是具体类。 如果无法做到这一点,请创建一个包含自动生成对象作为成员变量的域对象。

我使用Hibernate的方法是生成我随后扩展的基类。 我将所有业务逻辑(如果有的话)添加到这些子类中。 我经常最终也会更改Hibernate使用的FreeMarker模板,以进一步自定义生成的类。

AOP引用是一个很好的。 我将添加Spring,它内置了非常好的AOPfunction。

看一下

http://code.google.com/p/jaxb-method-inserter/

它是我写的JAXB的一个小插件,它的使用非常简单。 希望它有所帮助