JAXB 2的ObjectFactory类有什么意义?
我是使用JAXB的新手,我使用JAXB 2.1.3的xjc从我的XML Schema生成一组类。 除了为我的模式中的每个元素生成一个类之外,它还创build了一个ObjectFactory类。
似乎没有任何东西阻止我直接实例化元素,例如
MyElement element = new MyElement();
而教程似乎更喜欢
MyElement element = new ObjectFactory().createMyElement();
如果我看着ObjectFactory.java,我看到:
public MyElement createMyElement() { return new MyElement(); }
那么交易是什么? 我为什么要打扰ObjectFactory类呢? 我认为如果我要从一个改变的模式重新编译,它也将被覆盖。
向后兼容性不是唯一的原因。 😛
对于更复杂的模式,例如对元素内容可以采用的值进行复杂约束的模式,有时您需要创build实际的JAXBElement
对象。 它们通常不是手工创build的,所以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
映像!
正如@Chris所指出的那样,有时候JAXB不能和POJO一起工作,因为模式不能完全映射到Java。 在这些情况下, JAXBElement
包装器对象是提供附加types信息所必需的。
我经常遇到两个具体的例子。
-
如果你想编组一个没有
@XmlRootElement
注解的类的对象。 默认情况下,XJC只为某些元素生成@XmlRootElement
,而不为其他元素生成。 确切的逻辑有点复杂,但是可以强制XJC使用“简单绑定模式”生成更多的@XmlRootElement
类, -
当你的模式使用替代组。 这是非常高级的模式使用,但XJC通过大量使用
JAXBElement
包装将replace组转换为Java。
因此,在大量使用JAXBElement
的XJC生成的对象模型中(无论出于何种原因),您需要一种构build这些JAXBElement
实例的方法。 生成的ObjectFactory
是迄今为止最简单的方法。 你可以自己构build它们,但是它很笨重,容易出错。
向后兼容性,我猜…
http://weblogs.java.net/blog/kohsuke/archive/2005/08/a_story_of_migr.html :
…没有更多的ObjectFactory.createXYZ。 这些工厂方法的问题是,他们抛出一个检查JAXBException。 现在你可以简单地做新的XYZ(),不再有try / catch块。 (我知道,我知道,这是“我们在想什么?”的东西)…