Какой смысл в классах ObjectFactory JAXB 2? - PullRequest
94 голосов
/ 05 июня 2009

Я новичок в использовании JAXB, и я использовал xjc JAXB 2.1.3 для генерации набора классов из моей XML-схемы. В дополнение к созданию класса для каждого элемента в моей схеме он создал класс ObjectFactory.

Кажется, ничто не мешает мне создавать элементы напрямую, например,

MyElement element = new MyElement();

тогда как учебники предпочитают

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

Если я загляну в ObjectFactory.java, я увижу:

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

так в чем же дело? Зачем мне вообще держать класс ObjectFactory рядом? Я предполагаю, что он также будет перезаписан, если я буду перекомпилировать из измененной схемы.

Ответы [ 3 ]

65 голосов
/ 05 июня 2009

Обратная совместимость - не единственная причина. : -Р

С более сложными схемами, например, со сложными ограничениями на значения, которые может принимать содержимое элемента, иногда вам нужно создавать реальные 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 вручную!

38 голосов
/ 02 сентября 2009

Как указал @Chris, иногда JAXB не может работать с POJO, потому что схема не может быть точно привязана к Java. В этих случаях JAXBElement объекты-оболочки необходимы для предоставления дополнительной информации о типе.

Есть два конкретных примера, с которыми я столкнулся.

  • Если вы хотите маршалировать объект класса, у которого нет аннотации @XmlRootElement. По умолчанию XJC генерирует @XmlRootElement только для некоторых элементов, а не для других. Точная логика для этого немного сложна, но вы можете заставить XJC генерировать больше @XmlRootElement классов, используя «простой режим привязки»

  • Когда ваша схема использует группы замещения. Это довольно сложное использование схемы, но XJC переводит группы подстановки в Java, интенсивно используя JAXBElement оболочки.

Таким образом, в объектной модели, сгенерированной XJC, которая интенсивно использует JAXBElement (по любой причине), вам нужен способ создания этих JAXBElement экземпляров. Сгенерированный ObjectFactory - самый простой способ сделать это. Вы можете создать их самостоятельно, но это неуклюже и подвержено ошибкам.

9 голосов
/ 05 июня 2009

Обратная совместимость, наверное ...

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

... Нет больше ObjectFactory.createXYZ. Проблема с этими заводскими методами было то, что они бросили проверенный JAXBException. Теперь вы можете просто сделать новый XYZ (), больше нет блоков try / catch. (Я знаю, я знаю, ... это один из те "о чем мы думали !?" вещи) ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...