Browse Source

Revise concurrent JAXBContext creation towards computeIfAbsent

Closes gh-23879
pull/23893/head
Juergen Hoeller 5 years ago
parent
commit
19107649d2
  1. 2
      spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java
  2. 2
      spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java
  3. 27
      spring-web/src/main/java/org/springframework/http/codec/xml/JaxbContextContainer.java
  4. 15
      spring-web/src/main/java/org/springframework/http/converter/xml/AbstractJaxb2HttpMessageConverter.java

2
spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java

@ -221,7 +221,7 @@ public class Jaxb2XmlDecoder extends AbstractDecoder<Object> { @@ -221,7 +221,7 @@ public class Jaxb2XmlDecoder extends AbstractDecoder<Object> {
}
}
private Unmarshaller initUnmarshaller(Class<?> outputClass) throws JAXBException {
private Unmarshaller initUnmarshaller(Class<?> outputClass) throws CodecException, JAXBException {
Unmarshaller unmarshaller = this.jaxbContexts.createUnmarshaller(outputClass);
return this.unmarshallerProcessor.apply(unmarshaller);
}

2
spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java

@ -140,7 +140,7 @@ public class Jaxb2XmlEncoder extends AbstractSingleValueEncoder<Object> { @@ -140,7 +140,7 @@ public class Jaxb2XmlEncoder extends AbstractSingleValueEncoder<Object> {
}
}
private Marshaller initMarshaller(Class<?> clazz) throws JAXBException {
private Marshaller initMarshaller(Class<?> clazz) throws CodecException, JAXBException {
Marshaller marshaller = this.jaxbContexts.createMarshaller(clazz);
marshaller.setProperty(Marshaller.JAXB_ENCODING, StandardCharsets.UTF_8.name());
marshaller = this.marshallerProcessor.apply(marshaller);

27
spring-web/src/main/java/org/springframework/http/codec/xml/JaxbContextContainer.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -24,12 +24,13 @@ import javax.xml.bind.JAXBException; @@ -24,12 +24,13 @@ import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.springframework.util.Assert;
import org.springframework.core.codec.CodecException;
/**
* Holder for {@link JAXBContext} instances.
*
* @author Arjen Poutsma
* @author Juergen Hoeller
* @since 5.0
*/
final class JaxbContextContainer {
@ -37,24 +38,26 @@ final class JaxbContextContainer { @@ -37,24 +38,26 @@ final class JaxbContextContainer {
private final ConcurrentMap<Class<?>, JAXBContext> jaxbContexts = new ConcurrentHashMap<>(64);
public Marshaller createMarshaller(Class<?> clazz) throws JAXBException {
public Marshaller createMarshaller(Class<?> clazz) throws CodecException, JAXBException {
JAXBContext jaxbContext = getJaxbContext(clazz);
return jaxbContext.createMarshaller();
}
public Unmarshaller createUnmarshaller(Class<?> clazz) throws JAXBException {
public Unmarshaller createUnmarshaller(Class<?> clazz) throws CodecException, JAXBException {
JAXBContext jaxbContext = getJaxbContext(clazz);
return jaxbContext.createUnmarshaller();
}
private JAXBContext getJaxbContext(Class<?> clazz) throws JAXBException {
Assert.notNull(clazz, "Class must not be null");
JAXBContext jaxbContext = this.jaxbContexts.get(clazz);
if (jaxbContext == null) {
jaxbContext = JAXBContext.newInstance(clazz);
this.jaxbContexts.putIfAbsent(clazz, jaxbContext);
}
return jaxbContext;
private JAXBContext getJaxbContext(Class<?> clazz) throws CodecException {
return this.jaxbContexts.computeIfAbsent(clazz, key -> {
try {
return JAXBContext.newInstance(clazz);
}
catch (JAXBException ex) {
throw new CodecException(
"Could not create JAXBContext for class [" + clazz + "]: " + ex.getMessage(), ex);
}
});
}
}

15
spring-web/src/main/java/org/springframework/http/converter/xml/AbstractJaxb2HttpMessageConverter.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -25,7 +25,6 @@ import javax.xml.bind.Marshaller; @@ -25,7 +25,6 @@ import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.util.Assert;
/**
* Abstract base class for {@link org.springframework.http.converter.HttpMessageConverter HttpMessageConverters}
@ -106,19 +105,15 @@ public abstract class AbstractJaxb2HttpMessageConverter<T> extends AbstractXmlHt @@ -106,19 +105,15 @@ public abstract class AbstractJaxb2HttpMessageConverter<T> extends AbstractXmlHt
* @throws HttpMessageConversionException in case of JAXB errors
*/
protected final JAXBContext getJaxbContext(Class<?> clazz) {
Assert.notNull(clazz, "Class must not be null");
JAXBContext jaxbContext = this.jaxbContexts.get(clazz);
if (jaxbContext == null) {
return this.jaxbContexts.computeIfAbsent(clazz, key -> {
try {
jaxbContext = JAXBContext.newInstance(clazz);
this.jaxbContexts.putIfAbsent(clazz, jaxbContext);
return JAXBContext.newInstance(clazz);
}
catch (JAXBException ex) {
throw new HttpMessageConversionException(
"Could not instantiate JAXBContext for class [" + clazz + "]: " + ex.getMessage(), ex);
"Could not create JAXBContext for class [" + clazz + "]: " + ex.getMessage(), ex);
}
}
return jaxbContext;
});
}
}

Loading…
Cancel
Save