[java] JAXB 2의 ObjectFactory 클래스의 요점은 무엇입니까?

저는 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 클래스를 유지해야 하는가? 변경된 스키마에서 다시 컴파일하는 경우에도 덮어 쓸 것이라고 가정합니다.



답변

역 호환성이 유일한 이유는 아닙니다. :-피

요소의 내용이 취할 수있는 값에 대해 복잡한 제약이있는 스키마와 같이 더 복잡한 스키마의 경우 실제 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매번 손 으로 써야하는 영상 !


답변

@Chris가 지적했듯이 스키마가 Java에 정확히 매핑 될 수 없기 때문에 JAXB가 POJO와 함께 작동하지 않는 경우가 있습니다. 이러한 경우 JAXBElement추가 유형 정보를 제공하려면 래퍼 개체가 필요합니다.

이것이 흔한 곳에서 내가 본 두 가지 구체적인 예가 있습니다.

  • @XmlRootElement주석 이없는 클래스의 객체를 마샬링하려는 경우 . 기본적으로 XJC @XmlRootElement는 일부 요소에 대해서만 생성 하고 다른 요소에 대해서는 생성 하지 않습니다. 이에 대한 정확한 논리는 약간 복잡하지만 “단순 바인딩 모드”를@XmlRootElement 사용하여 XJC가 더 많은 클래스 를 생성하도록 강제 할 수 있습니다.

  • 스키마가 대체 그룹을 사용하는 경우. 이것은 꽤 고급 스키마 사용이지만 XJC는 JAXBElement랩퍼 를 많이 사용하여 대체 그룹을 Java로 변환 합니다.

따라서 JAXBElement(어떤 이유로 든) 많이 사용하는 XJC 생성 개체 모델에서 이러한 JAXBElement인스턴스 를 구성하는 방법이 필요 합니다. 생성 된 ObjectFactory것이 가장 쉬운 방법입니다. 당신은 할 수 있습니다 그들에게 자신을 구성,하지만 어설픈 오류가 발생하기 쉬운 그렇게 할 수 있습니다.


답변

이전 버전과의 호환성, 나는 추측한다 …

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

… 더 이상 ObjectFactory.createXYZ가 없습니다. 이러한 팩토리 메소드의 문제점은 확인 된 JAXBException을 던진다는 것입니다. 이제 더 이상 try / catch 블록이 아닌 new XYZ ()를 수행 할 수 있습니다. (알아요, 알아요 … 이건 “우리가 무슨 생각을하고 있었나요!?”라는 것 중 하나입니다) …


답변