JAXB 2 的 ObjectFactory 类有什么意义?

2022-08-31 10:11:56

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

似乎没有什么能阻止我直接实例化元素,例如

MyElement element = new MyElement();

而教程似乎更喜欢

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

如果我看一下ObjectFactory.java,我会看到:

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

那有什么关系呢?我为什么要费心保留 ObjectFactory 类呢?我假设如果我从更改的架构重新编译,它也将被覆盖。


答案 1

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

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

@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));

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


答案 2

正如@Chris所指出的,有时 JAXB 不能与 POJO 一起使用,因为模式不能完全映射到 Java。在这些情况下,包装对象是提供其他类型信息所必需的。JAXBElement

我遇到过两个具体的例子,这很常见。

  • 如果要封送没有批注的类的对象。默认情况下,XJC 仅为某些元素生成,而不为其他元素生成。确切的逻辑有点复杂,但你可以强制XJC使用“简单绑定模式”生成更多的类。@XmlRootElement@XmlRootElement@XmlRootElement

  • 当架构使用替换基组时。这是非常高级的模式用法,但是XJC通过大量使用包装器将替换组转换为Java。JAXBElement

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


推荐