SPR-5745 - Support lazy initialization within Jaxb2 OXM classes
This commit is contained in:
parent
1dc346a32c
commit
58d3e704bf
|
|
@ -140,6 +140,8 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, BeanCl
|
||||||
|
|
||||||
private Schema schema;
|
private Schema schema;
|
||||||
|
|
||||||
|
private boolean lazyInit = false;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a JAXB context path.
|
* Set a JAXB context path.
|
||||||
|
|
@ -259,31 +261,53 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, BeanCl
|
||||||
this.mtomEnabled = mtomEnabled;
|
this.mtomEnabled = mtomEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether to lazily initialize the {@link JAXBContext} for this marshaller.
|
||||||
|
* Default is {@code false} to initialize on startup; can be switched to
|
||||||
|
* {@code true}.
|
||||||
|
* <p>Early initialization just applies if <code>afterPropertiesSet()</code> is called.
|
||||||
|
* @see #afterPropertiesSet()
|
||||||
|
*/
|
||||||
|
public void setLazyInit(boolean lazyInit) {
|
||||||
|
this.lazyInit = lazyInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||||
this.beanClassLoader = classLoader;
|
this.beanClassLoader = classLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public final void afterPropertiesSet() throws Exception {
|
public final void afterPropertiesSet() throws Exception {
|
||||||
this.jaxbContext = createJaxbContext();
|
if (StringUtils.hasLength(this.contextPath) && !ObjectUtils.isEmpty(this.classesToBeBound)) {
|
||||||
|
throw new IllegalArgumentException("Specify either 'contextPath' or 'classesToBeBound property'; not both");
|
||||||
|
}
|
||||||
|
else if (!StringUtils.hasLength(this.contextPath) && ObjectUtils.isEmpty(this.classesToBeBound)) {
|
||||||
|
throw new IllegalArgumentException("Setting either 'contextPath' or 'classesToBeBound' is required");
|
||||||
|
}
|
||||||
|
if (!lazyInit) {
|
||||||
|
getJaxbContext();
|
||||||
|
}
|
||||||
if (!ObjectUtils.isEmpty(this.schemaResources)) {
|
if (!ObjectUtils.isEmpty(this.schemaResources)) {
|
||||||
this.schema = loadSchema(this.schemaResources, this.schemaLanguage);
|
this.schema = loadSchema(this.schemaResources, this.schemaLanguage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected JAXBContext createJaxbContext() throws Exception {
|
protected synchronized JAXBContext getJaxbContext() {
|
||||||
if (StringUtils.hasLength(this.contextPath) && !ObjectUtils.isEmpty(this.classesToBeBound)) {
|
if (this.jaxbContext == null) {
|
||||||
throw new IllegalArgumentException("Specify either 'contextPath' or 'classesToBeBound property'; not both");
|
try {
|
||||||
}
|
if (StringUtils.hasLength(this.contextPath)) {
|
||||||
if (StringUtils.hasLength(this.contextPath)) {
|
this.jaxbContext = createJaxbContextFromContextPath();
|
||||||
return createJaxbContextFromContextPath();
|
}
|
||||||
}
|
else if (!ObjectUtils.isEmpty(this.classesToBeBound)) {
|
||||||
else if (!ObjectUtils.isEmpty(this.classesToBeBound)) {
|
this.jaxbContext = createJaxbContextFromClasses();
|
||||||
return createJaxbContextFromClasses();
|
}
|
||||||
}
|
}
|
||||||
else {
|
catch (JAXBException ex) {
|
||||||
throw new IllegalArgumentException("setting either contextPath or classesToBeBound is required");
|
throw convertJaxbException(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return jaxbContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JAXBContext createJaxbContextFromContextPath() throws JAXBException {
|
private JAXBContext createJaxbContextFromContextPath() throws JAXBException {
|
||||||
|
|
@ -364,7 +388,6 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, BeanCl
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Marshalling
|
// Marshalling
|
||||||
|
|
||||||
public void marshal(Object graph, Result result) throws XmlMappingException {
|
public void marshal(Object graph, Result result) throws XmlMappingException {
|
||||||
|
|
@ -410,7 +433,7 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, BeanCl
|
||||||
*/
|
*/
|
||||||
protected Marshaller createMarshaller() {
|
protected Marshaller createMarshaller() {
|
||||||
try {
|
try {
|
||||||
Marshaller marshaller = this.jaxbContext.createMarshaller();
|
Marshaller marshaller = getJaxbContext().createMarshaller();
|
||||||
initJaxbMarshaller(marshaller);
|
initJaxbMarshaller(marshaller);
|
||||||
return marshaller;
|
return marshaller;
|
||||||
}
|
}
|
||||||
|
|
@ -495,7 +518,7 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, BeanCl
|
||||||
*/
|
*/
|
||||||
protected Unmarshaller createUnmarshaller() {
|
protected Unmarshaller createUnmarshaller() {
|
||||||
try {
|
try {
|
||||||
Unmarshaller unmarshaller = this.jaxbContext.createUnmarshaller();
|
Unmarshaller unmarshaller = getJaxbContext().createUnmarshaller();
|
||||||
initJaxbUnmarshaller(unmarshaller);
|
initJaxbUnmarshaller(unmarshaller);
|
||||||
return unmarshaller;
|
return unmarshaller;
|
||||||
}
|
}
|
||||||
|
|
@ -557,7 +580,6 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, BeanCl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class Jaxb2AttachmentMarshaller extends AttachmentMarshaller {
|
private static class Jaxb2AttachmentMarshaller extends AttachmentMarshaller {
|
||||||
|
|
||||||
private final MimeContainer mimeContainer;
|
private final MimeContainer mimeContainer;
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,13 @@ import java.lang.reflect.Method;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import javax.activation.DataHandler;
|
import javax.activation.DataHandler;
|
||||||
import javax.activation.FileDataSource;
|
import javax.activation.FileDataSource;
|
||||||
import javax.xml.bind.JAXBException;
|
|
||||||
import javax.xml.transform.Result;
|
import javax.xml.transform.Result;
|
||||||
import javax.xml.transform.sax.SAXResult;
|
import javax.xml.transform.sax.SAXResult;
|
||||||
import javax.xml.transform.stream.StreamResult;
|
import javax.xml.transform.stream.StreamResult;
|
||||||
|
|
||||||
|
import static org.custommonkey.xmlunit.XMLAssert.*;
|
||||||
import static org.easymock.EasyMock.*;
|
import static org.easymock.EasyMock.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertTrue;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.xml.sax.Attributes;
|
import org.xml.sax.Attributes;
|
||||||
import org.xml.sax.ContentHandler;
|
import org.xml.sax.ContentHandler;
|
||||||
|
|
@ -37,6 +37,7 @@ import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.oxm.AbstractMarshallerTests;
|
import org.springframework.oxm.AbstractMarshallerTests;
|
||||||
import org.springframework.oxm.Marshaller;
|
import org.springframework.oxm.Marshaller;
|
||||||
|
import org.springframework.oxm.UncategorizedMappingException;
|
||||||
import org.springframework.oxm.XmlMappingException;
|
import org.springframework.oxm.XmlMappingException;
|
||||||
import org.springframework.oxm.jaxb.test.FlightType;
|
import org.springframework.oxm.jaxb.test.FlightType;
|
||||||
import org.springframework.oxm.jaxb.test.Flights;
|
import org.springframework.oxm.jaxb.test.Flights;
|
||||||
|
|
@ -94,6 +95,18 @@ public class Jaxb2MarshallerTests extends AbstractMarshallerTests {
|
||||||
verify(handlerMock);
|
verify(handlerMock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void laxyInit() throws Exception {
|
||||||
|
marshaller = new Jaxb2Marshaller();
|
||||||
|
marshaller.setContextPath(CONTEXT_PATH);
|
||||||
|
marshaller.setLazyInit(true);
|
||||||
|
marshaller.afterPropertiesSet();
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
StreamResult result = new StreamResult(writer);
|
||||||
|
marshaller.marshal(flights, result);
|
||||||
|
assertXMLEqual("Marshaller writes invalid StreamResult", EXPECTED_STRING, writer.toString());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void properties() throws Exception {
|
public void properties() throws Exception {
|
||||||
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
|
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
|
||||||
|
|
@ -110,7 +123,7 @@ public class Jaxb2MarshallerTests extends AbstractMarshallerTests {
|
||||||
marshaller.afterPropertiesSet();
|
marshaller.afterPropertiesSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = JAXBException.class)
|
@Test(expected = UncategorizedMappingException.class)
|
||||||
public void testInvalidContextPath() throws Exception {
|
public void testInvalidContextPath() throws Exception {
|
||||||
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
|
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
|
||||||
marshaller.setContextPath("ab");
|
marshaller.setContextPath("ab");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue