JAXB 2的ObjectFactory类有什么意义?

时间:2009-06-05 00:10:49

标签: java jaxb

我是使用JAXB的新手,我使用JAXB 2.1.3的xjc从我的XML Schema生成一组类。除了为我的模式中的每个元素生成一个类之外,它还创建了一个ObjectFactory类。

似乎没有任何阻止我直接实例化元素的东西,例如。

MyElement element = new MyElement();

而教程似乎更喜欢

MyElement element = new ObjectFactory().createMyElement();

如果我查看ObjectFactory.java,我会看到:

public MyElement createMyElement() {
    return new MyElement();
}

那么这笔交易是什么?为什么我甚至不打扰保持ObjectFactory类?我假设如果我从更改的模式重新编译它也将被覆盖。

3 个答案:

答案 0 :(得分:64)

向后兼容性不是唯一的原因。 :-P

对于更复杂的模式,例如对元素内容可以采用的值具有复杂约束的模式,有时需要创建实际的JAXBElement对象。它们通常不是手工创建的微不足道的,因此create*方法为您的努力工作。示例(来自XHTML 1.1架构):

@XmlElementDecl(namespace = "http://www.w3.org/1999/xhtml", name = "style", scope = XhtmlHeadType.class)
public JAXBElement<XhtmlStyleType> createXhtmlHeadTypeStyle(XhtmlStyleType value) {
    return new JAXBElement<XhtmlStyleType>(_XhtmlHeadTypeStyle_QNAME, XhtmlStyleType.class, XhtmlHeadType.class, value);
}

这是<style>代码中<head>标记的获取方式:

ObjectFactory factory = new ObjectFactory();
XhtmlHtmlType html = factory.createXhtmlHtmlType();
XhtmlHeadType head = factory.createXhtmlHeadType();
html.setHead(head);
XhtmlStyleType style = factory.createXhtmlStyleType();
head.getContent().add(factory.createXhtmlHeadTypeStyle(style));

ObjectFactory的前三个用法可能被认为是多余的(尽管对于一致性很有用),但第四个用途使JAXB更容易使用。成像必须每次手动写出new JAXBElement

答案 1 :(得分:38)

正如@Chris指出的那样,有时JAXB无法使用POJO,因为架构无法准确映射到Java。在这些情况下,JAXBElement包装器对象是提供其他类型信息所必需的。

我遇到过两个具体的例子。

  • 如果要封送没有@XmlRootElement注释的类的对象。默认情况下,XJC仅为某些元素生成@XmlRootElement,而不为其他元素生成@XmlRootElement。这方面的确切逻辑有点复杂,但您可以使用"simple binding mode"

  • 强制XJC生成更多JAXBElement
  • 当您的架构使用替换组时。这是非常高级的架构用法,但是XJC通过大量使用JAXBElement包装器将替换组转换为Java。

因此,在XJC生成的对象模型中,大量使用JAXBElement(无论出于何种原因),您需要一种构造ObjectFactory实例的方法。生成的{{1}}是迄今为止最简单的方法。你可以自己构建它们,但这样做很笨拙且容易出错。

答案 2 :(得分:9)

向后兼容性,我猜......

http://weblogs.java.net/blog/kohsuke/archive/2005/08/a_story_of_migr.html

  

...不再是ObjectFactory.createXYZ。   这些工厂方法的问题   是他们扔了一个检查   JAXBException。现在你可以做到   新的XYZ(),没有更多的try / catch块。   (我知道,我知道,......这是其中之一   那些“我们在想什么!?”   的东西)...