如何扩展由 JAXB、CXF 或 Hibernate 工具生成的 Java 代码?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/780567/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I extend Java code generated by JAXB, CXF or Hibernate tools?
提问by mjn
With generated Java source code, like
使用生成的 Java 源代码,例如
- code generated with Hibernate tools
- code generated with JAXB schema binding (xjc)
- code generated with WDSL2Java (cxf)
- 使用 Hibernate 工具生成的代码
- 使用 JAXB 模式绑定 (xjc) 生成的代码
- 用 WDSL2Java (cxf) 生成的代码
all generated classes are "value object" types, without business logic. And if I add methods to the generated source code, I will loose these methods if I repeat the source code generation.
所有生成的类都是“值对象”类型,没有业务逻辑。如果我向生成的源代码添加方法,如果我重复源代码生成,我将失去这些方法。
Do these Java code generation tools offer ways to "extend" the generated code?
这些 Java 代码生成工具是否提供了“扩展”生成代码的方法?
For example,
例如,
- to override the ToString method (for logging)
- to implement the visitor pattern (for data analysis / validation)
- 覆盖 ToString 方法(用于记录)
- 实现访问者模式(用于数据分析/验证)
采纳答案by Brian Agnew
For JAXB, see Adding Behaviours.
对于 JAXB,请参阅添加行为。
Basically, you configure JAXB to return a custom instance of the object you'd normally expect. In the below example you create a new object PersonEx which extends the JAXB object Person. This mechanism works well in that you're deriving from the generated classes, and not altering the JAXB classes or schemas at all.
基本上,您将 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();
}
}
Note that the @Override directive is important in case your JAXB object changes - it will prevent your customisation becoming orphaned.
请注意,@Override 指令很重要,以防您的 JAXB 对象发生更改 - 它会防止您的自定义成为孤立的。
回答by Manrico Corazzi
As for Hibernate you may tweak the template files used in code generation to change their behaviour. If you want to tweak the HIbernate Tools you can edit, for example: dao/daohome.ftl
至于 Hibernate,您可以调整代码生成中使用的模板文件来改变它们的行为。如果你想调整 HIbernate 工具,你可以编辑,例如:dao/daohome.ftl
You may even add fields to the "toString()" output editing the .hbm.xmlfiles
您甚至可以在编辑.hbm.xml文件的“toString()”输出中添加字段
...
<property name="note" type="string">
<meta attribute="use-in-tostring">true</meta>
<column name="note" />
</property>
...
Both for logging and validation you may consider using AOP with AspectJ(I don't recommend messing with the generated code, since you might want to build that from scratch many times over).
对于日志记录和验证,您可以考虑将AOP 与 AspectJ 一起使用(我不建议弄乱生成的代码,因为您可能希望从头开始多次构建)。
回答by ShuggyCoUk
First I would reiterate that modification of generated code has many problems associated with it and that, where possible it should be avoided. That said sometimes this is impractical to avoid or more effort than just dealing with the changes when the code is regenerated.
首先,我要重申,修改生成的代码有很多与之相关的问题,在可能的情况下应该避免。也就是说,有时这是不切实际的,要避免或比仅在重新生成代码时处理更改更努力。
Sadly java doesn't support the concept of partial classes that c# has. These are precisely to solve this sort of problem.
遗憾的是,java 不支持 c# 具有的部分类的概念。这些正是为了解决这类问题。
You should see if your code generation tools support some form of meaningful comments which delimit regions added by yourself in the class (this is unlikely and won't help if you are modifying the code rather than adding to it)
您应该查看您的代码生成工具是否支持某种形式的有意义的注释来分隔您在类中添加的区域(如果您是修改代码而不是添加代码,这不太可能,也无济于事)
You best option if you really wish to do this is to generate the files initially but check them into a version control repository immediately. Then make your changes, check that in.
如果您真的希望这样做,最好的选择是最初生成文件,但立即将它们签入版本控制存储库。然后进行更改,签入。
Next time you rerun the tools and let them overwrite the existing files you can diff against your source controlled ones and merge the changes back in (most trivial changes like addition of new columns/tables will be little effort.
下次您重新运行这些工具并让它们覆盖现有文件时,您可以与源代码控制的文件进行比较,并将更改合并回(大多数微不足道的更改,例如添加新列/表,将不费吹灰之力。
This will not help you as much if the code generator suddenly generates radically different code (say a new version) but in those cases any code you added which wasn't simply additional convenience methods relying on data/methods already exposed publicly) will have problems no matter how it is mixed into the class. The version control system does still help however since it also records the original changesso you can see what you had added previously and what, one would assume, you need to recreate in the new style.
如果代码生成器突然生成完全不同的代码(比如新版本),这对您没有多大帮助,但在这种情况下,您添加的任何代码(不仅仅是依赖于已经公开公开的数据/方法的附加便利方法)都会有问题不管它是怎么混入类的。然而,版本控制系统仍然有帮助,因为它还会记录原始更改,因此您可以查看您之前添加的内容以及您认为需要以新样式重新创建的内容。
回答by kgiannakakis
It is not a good idea to edit generated code files, either by editing the files them selves or by subclassing. Whatever you do, be sure to leave the signature created by the tool intact, so that it will be possible to understand in the future that the file was auto-generated.
通过编辑文件本身或通过子类化来编辑生成的代码文件并不是一个好主意。无论您做什么,请务必保留该工具创建的签名完整无缺,以便将来可以了解该文件是自动生成的。
I recommend that you research the command options of the tools to see if they allow you some flexibility. Some tools can generate abstract classes or interfaces instead of concrete classes. If this is not possible, create a domain object that includes the autogenerated object as a member variable.
我建议您研究这些工具的命令选项,看看它们是否允许您具有一定的灵活性。一些工具可以生成抽象类或接口而不是具体类。如果这是不可能的,请创建一个域对象,其中包含自动生成的对象作为成员变量。
回答by willcodejavaforfood
The way I have used Hibernate is to generate base classes that I then extend. I add all my business logic (if any) to these subclasses. I quite often also end up changing the FreeMarker templates used by Hibernate to further customize the generated classes.
我使用 Hibernate 的方式是生成我然后扩展的基类。我将所有业务逻辑(如果有)添加到这些子类中。我也经常最终更改 Hibernate 使用的 FreeMarker 模板以进一步自定义生成的类。
回答by Jon
Have a look at
看一下
http://code.google.com/p/jaxb-method-inserter/
http://code.google.com/p/jaxb-method-inserter/
Its a small plugin for JAXB I wrote, Its quite simple to uses. Hope it help
它是我为 JAXB 编写的一个小插件,使用起来非常简单。希望有帮助
回答by duffymo
The AOP citation is a good one. I'll add Spring, which has very nice AOP features built in.
AOP 引用是一个很好的引用。我将添加 Spring,它内置了非常好的 AOP 功能。

