Skip to content

Commit

Permalink
Revise concurrent JAXBContext creation towards computeIfAbsent
Browse files Browse the repository at this point in the history
Closes gh-23879
  • Loading branch information
jhoeller committed Oct 30, 2019
1 parent 42e7ade commit 1910764
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ private Object unmarshal(List<XMLEvent> events, Class<?> outputClass) {
}
}

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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public DataBuffer encodeValue(Object value, DataBufferFactory bufferFactory,
}
}

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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -24,37 +24,40 @@
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 {

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);
}
});
}

}
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -25,7 +25,6 @@
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}
Expand Down Expand Up @@ -106,19 +105,15 @@ protected void customizeUnmarshaller(Unmarshaller unmarshaller) {
* @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;
});
}

}

0 comments on commit 1910764

Please sign in to comment.