102

我是使用 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 类?如果我要从更改的模式重新编译,我认为它也会被覆盖。

4

3 回答 3

71

向后兼容性并不是唯一的原因。:-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成像每次都要手写一个!

于 2009-06-05T01:17:19.503 回答
41

正如@Chris 指出的那样,有时 JAXB 无法与 POJO 一起使用,因为架构无法准确映射到 Java。在这些情况下,JAXBElement需要包装对象来提供额外的类型信息。

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

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

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

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

于 2009-09-02T12:30:54.213 回答
9

向后兼容性,我猜...

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

...不再有 ObjectFactory.createXYZ。这些工厂方法的问题在于它们抛出了一个检查过的 JAXBException。现在您可以简单地执行 new XYZ(),不再需要 try/catch 块。(我知道,我知道,......这是那些“我们在想什么!?”的事情之一)......

于 2009-06-05T00:45:16.527 回答