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块。 (我知道,我知道,这是“我们在想什么?”的东西)…