Use shared BindConverter when possible

Update the `Binder` so that a single shares static `BindConverter` is
used whenever possible.

Closes gh-14562
pull/14560/merge
Phillip Webb 6 years ago
parent 865b7ae47f
commit 2bc3d8d01f

@ -47,7 +47,7 @@ import org.springframework.util.Assert;
* @author Phillip Webb
* @author Andy Wilkinson
*/
class BindConverter {
final class BindConverter {
private static final Set<Class<?>> EXCLUDED_EDITORS;
static {
@ -56,9 +56,11 @@ class BindConverter {
EXCLUDED_EDITORS = Collections.unmodifiableSet(excluded);
}
private static BindConverter sharedInstance;
private final ConversionService conversionService;
BindConverter(ConversionService conversionService,
private BindConverter(ConversionService conversionService,
Consumer<PropertyEditorRegistry> propertyEditorInitializer) {
Assert.notNull(conversionService, "ConversionService must not be null");
List<ConversionService> conversionServices = getConversionServices(
@ -97,6 +99,21 @@ class BindConverter {
new ResolvableTypeDescriptor(type, annotations));
}
public static BindConverter get(ConversionService conversionService,
Consumer<PropertyEditorRegistry> propertyEditorInitializer) {
if (conversionService == ApplicationConversionService.getSharedInstance()
&& propertyEditorInitializer == null) {
BindConverter instance = sharedInstance;
if (instance == null) {
instance = new BindConverter(conversionService,
propertyEditorInitializer);
sharedInstance = instance;
}
return instance;
}
return new BindConverter(conversionService, propertyEditorInitializer);
}
/**
* A {@link TypeDescriptor} backed by a {@link ResolvableType}.
*/

@ -392,7 +392,7 @@ public class Binder {
private ConfigurationProperty configurationProperty;
Context() {
this.converter = new BindConverter(Binder.this.conversionService,
this.converter = BindConverter.get(Binder.this.conversionService,
Binder.this.propertyEditorInitializer);
}

@ -65,17 +65,17 @@ public class BindConverterTests {
public void createWhenConversionServiceIsNullShouldThrowException() {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("ConversionService must not be null");
new BindConverter(null, null);
BindConverter.get(null, null);
}
@Test
public void createWhenPropertyEditorInitializerIsNullShouldCreate() {
new BindConverter(ApplicationConversionService.getSharedInstance(), null);
BindConverter.get(ApplicationConversionService.getSharedInstance(), null);
}
@Test
public void createWhenPropertyEditorInitializerIsNotNullShouldUseToInitialize() {
new BindConverter(ApplicationConversionService.getSharedInstance(),
BindConverter.get(ApplicationConversionService.getSharedInstance(),
this.propertyEditorInitializer);
verify(this.propertyEditorInitializer).accept(any(PropertyEditorRegistry.class));
}
@ -128,8 +128,8 @@ public class BindConverterTests {
@Test
public void canConvertWhenNotPropertyEditorAndConversionServiceCannotConvertShouldReturnFalse() {
BindConverter bindConverter = new BindConverter(
ApplicationConversionService.getSharedInstance(), null);
BindConverter bindConverter = BindConverter
.get(ApplicationConversionService.getSharedInstance(), null);
assertThat(bindConverter.canConvert("test",
ResolvableType.forClass(SampleType.class))).isFalse();
}
@ -189,8 +189,8 @@ public class BindConverterTests {
@Test
public void convertWhenNotPropertyEditorAndConversionServiceCannotConvertShouldThrowException() {
BindConverter bindConverter = new BindConverter(
ApplicationConversionService.getSharedInstance(), null);
BindConverter bindConverter = BindConverter
.get(ApplicationConversionService.getSharedInstance(), null);
this.thrown.expect(ConverterNotFoundException.class);
bindConverter.convert("test", ResolvableType.forClass(SampleType.class));
}
@ -199,7 +199,7 @@ public class BindConverterTests {
public void convertWhenConvertingToFileShouldExcludeFileEditor() {
// For back compatibility we want true file conversion and not an accidental
// classpath resource reference. See gh-12163
BindConverter bindConverter = new BindConverter(new GenericConversionService(),
BindConverter bindConverter = BindConverter.get(new GenericConversionService(),
null);
File result = bindConverter.convert(".", ResolvableType.forClass(File.class));
assertThat(result.getPath()).isEqualTo(".");
@ -207,7 +207,7 @@ public class BindConverterTests {
@Test
public void fallsBackToApplicationConversionService() {
BindConverter bindConverter = new BindConverter(new GenericConversionService(),
BindConverter bindConverter = BindConverter.get(new GenericConversionService(),
null);
Duration result = bindConverter.convert("10s",
ResolvableType.forClass(Duration.class));
@ -216,14 +216,14 @@ public class BindConverterTests {
private BindConverter getPropertyEditorOnlyBindConverter(
Consumer<PropertyEditorRegistry> propertyEditorInitializer) {
return new BindConverter(new ThrowingConversionService(),
return BindConverter.get(new ThrowingConversionService(),
propertyEditorInitializer);
}
private BindConverter getBindConverter(Converter<?, ?> converter) {
GenericConversionService conversionService = new GenericConversionService();
conversionService.addConverter(converter);
return new BindConverter(conversionService, null);
return BindConverter.get(conversionService, null);
}
private void registerSampleTypeEditor(PropertyEditorRegistry registry) {

Loading…
Cancel
Save