首页 文章

's the point of JAXB 2'的ObjectFactory类是什么?

提问于
浏览
87

我是使用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 回答

  • 61

    向后兼容性不是唯一的原因 . :-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

  • 35

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

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

    • 如果要编组没有 @XmlRootElement 注释的类的对象 . 默认情况下,XJC仅为某些元素生成 @XmlRootElement ,而不为其他元素生成 @XmlRootElement . 这个的确切逻辑有点复杂,但您可以强制XJC使用"simple binding mode"生成更多 @XmlRootElement

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

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

  • 9

    我认为向后兼容性......

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

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

相关问题