18

使用生成的 Java 源代码,例如

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

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

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

例如,

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

7 回答 7

15

对于 JAXB,请参阅添加行为

基本上,您将 JAXB 配置为返回您通常期望的对象的自定义实例。在下面的示例中,您将创建一个扩展 JAXB 对象 Person 的新对象 PersonEx。这种机制运行良好,因为您是从生成的类派生的,根本不改变 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();
  }
}

请注意,如果您的 JAXB 对象发生更改,@Override 指令很重要——它将防止您的自定义成为孤立的。

于 2009-04-23T09:20:03.327 回答
8

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

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

...
<property name="note" type="string">
    <meta attribute="use-in-tostring">true</meta>
    <column name="note" />
</property>
...

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

于 2009-04-23T07:41:02.643 回答
4

首先,我要重申,修改生成的代码有很多与之相关的问题,应该尽可能避免。也就是说,有时避免或比仅在重新生成代码时处理更改更努力是不切实际的。

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

您应该查看您的代码生成工具是否支持某种形式的有意义的注释,这些注释分隔您在类中添加的区域(如果您正在修改代码而不是添加代码,这不太可能并且无济于事)

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

下次您重新运行工具并让它们覆盖现有文件时,您可以与源代码控制的文件进行比较并将更改合并回来(大多数琐碎的更改,例如添加新列/表将不费吹灰之力。

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

于 2009-04-23T07:42:49.377 回答
3

编辑生成的代码文件不是一个好主意,无论是通过编辑文件本身还是通过子类化。无论您做什么,请务必保持该工具创建的签名完好无损,以便将来可以了解该文件是自动生成的。

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

于 2009-04-23T07:34:46.760 回答
3

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

于 2009-04-23T10:06:09.440 回答
1

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

于 2009-04-23T09:59:06.693 回答
1

看一下

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

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

于 2011-01-25T14:10:50.763 回答