Use shared BindConverter when possible
Update the `Binder` so that a single shares static `BindConverter` is used whenever possible. Closes gh-14562
This commit is contained in:
parent
865b7ae47f
commit
2bc3d8d01f
|
|
@ -47,7 +47,7 @@ import org.springframework.util.Assert;
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
* @author Andy Wilkinson
|
* @author Andy Wilkinson
|
||||||
*/
|
*/
|
||||||
class BindConverter {
|
final class BindConverter {
|
||||||
|
|
||||||
private static final Set<Class<?>> EXCLUDED_EDITORS;
|
private static final Set<Class<?>> EXCLUDED_EDITORS;
|
||||||
static {
|
static {
|
||||||
|
|
@ -56,9 +56,11 @@ class BindConverter {
|
||||||
EXCLUDED_EDITORS = Collections.unmodifiableSet(excluded);
|
EXCLUDED_EDITORS = Collections.unmodifiableSet(excluded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static BindConverter sharedInstance;
|
||||||
|
|
||||||
private final ConversionService conversionService;
|
private final ConversionService conversionService;
|
||||||
|
|
||||||
BindConverter(ConversionService conversionService,
|
private BindConverter(ConversionService conversionService,
|
||||||
Consumer<PropertyEditorRegistry> propertyEditorInitializer) {
|
Consumer<PropertyEditorRegistry> propertyEditorInitializer) {
|
||||||
Assert.notNull(conversionService, "ConversionService must not be null");
|
Assert.notNull(conversionService, "ConversionService must not be null");
|
||||||
List<ConversionService> conversionServices = getConversionServices(
|
List<ConversionService> conversionServices = getConversionServices(
|
||||||
|
|
@ -97,6 +99,21 @@ class BindConverter {
|
||||||
new ResolvableTypeDescriptor(type, annotations));
|
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}.
|
* A {@link TypeDescriptor} backed by a {@link ResolvableType}.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -392,7 +392,7 @@ public class Binder {
|
||||||
private ConfigurationProperty configurationProperty;
|
private ConfigurationProperty configurationProperty;
|
||||||
|
|
||||||
Context() {
|
Context() {
|
||||||
this.converter = new BindConverter(Binder.this.conversionService,
|
this.converter = BindConverter.get(Binder.this.conversionService,
|
||||||
Binder.this.propertyEditorInitializer);
|
Binder.this.propertyEditorInitializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,17 +65,17 @@ public class BindConverterTests {
|
||||||
public void createWhenConversionServiceIsNullShouldThrowException() {
|
public void createWhenConversionServiceIsNullShouldThrowException() {
|
||||||
this.thrown.expect(IllegalArgumentException.class);
|
this.thrown.expect(IllegalArgumentException.class);
|
||||||
this.thrown.expectMessage("ConversionService must not be null");
|
this.thrown.expectMessage("ConversionService must not be null");
|
||||||
new BindConverter(null, null);
|
BindConverter.get(null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createWhenPropertyEditorInitializerIsNullShouldCreate() {
|
public void createWhenPropertyEditorInitializerIsNullShouldCreate() {
|
||||||
new BindConverter(ApplicationConversionService.getSharedInstance(), null);
|
BindConverter.get(ApplicationConversionService.getSharedInstance(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createWhenPropertyEditorInitializerIsNotNullShouldUseToInitialize() {
|
public void createWhenPropertyEditorInitializerIsNotNullShouldUseToInitialize() {
|
||||||
new BindConverter(ApplicationConversionService.getSharedInstance(),
|
BindConverter.get(ApplicationConversionService.getSharedInstance(),
|
||||||
this.propertyEditorInitializer);
|
this.propertyEditorInitializer);
|
||||||
verify(this.propertyEditorInitializer).accept(any(PropertyEditorRegistry.class));
|
verify(this.propertyEditorInitializer).accept(any(PropertyEditorRegistry.class));
|
||||||
}
|
}
|
||||||
|
|
@ -128,8 +128,8 @@ public class BindConverterTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void canConvertWhenNotPropertyEditorAndConversionServiceCannotConvertShouldReturnFalse() {
|
public void canConvertWhenNotPropertyEditorAndConversionServiceCannotConvertShouldReturnFalse() {
|
||||||
BindConverter bindConverter = new BindConverter(
|
BindConverter bindConverter = BindConverter
|
||||||
ApplicationConversionService.getSharedInstance(), null);
|
.get(ApplicationConversionService.getSharedInstance(), null);
|
||||||
assertThat(bindConverter.canConvert("test",
|
assertThat(bindConverter.canConvert("test",
|
||||||
ResolvableType.forClass(SampleType.class))).isFalse();
|
ResolvableType.forClass(SampleType.class))).isFalse();
|
||||||
}
|
}
|
||||||
|
|
@ -189,8 +189,8 @@ public class BindConverterTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void convertWhenNotPropertyEditorAndConversionServiceCannotConvertShouldThrowException() {
|
public void convertWhenNotPropertyEditorAndConversionServiceCannotConvertShouldThrowException() {
|
||||||
BindConverter bindConverter = new BindConverter(
|
BindConverter bindConverter = BindConverter
|
||||||
ApplicationConversionService.getSharedInstance(), null);
|
.get(ApplicationConversionService.getSharedInstance(), null);
|
||||||
this.thrown.expect(ConverterNotFoundException.class);
|
this.thrown.expect(ConverterNotFoundException.class);
|
||||||
bindConverter.convert("test", ResolvableType.forClass(SampleType.class));
|
bindConverter.convert("test", ResolvableType.forClass(SampleType.class));
|
||||||
}
|
}
|
||||||
|
|
@ -199,7 +199,7 @@ public class BindConverterTests {
|
||||||
public void convertWhenConvertingToFileShouldExcludeFileEditor() {
|
public void convertWhenConvertingToFileShouldExcludeFileEditor() {
|
||||||
// For back compatibility we want true file conversion and not an accidental
|
// For back compatibility we want true file conversion and not an accidental
|
||||||
// classpath resource reference. See gh-12163
|
// classpath resource reference. See gh-12163
|
||||||
BindConverter bindConverter = new BindConverter(new GenericConversionService(),
|
BindConverter bindConverter = BindConverter.get(new GenericConversionService(),
|
||||||
null);
|
null);
|
||||||
File result = bindConverter.convert(".", ResolvableType.forClass(File.class));
|
File result = bindConverter.convert(".", ResolvableType.forClass(File.class));
|
||||||
assertThat(result.getPath()).isEqualTo(".");
|
assertThat(result.getPath()).isEqualTo(".");
|
||||||
|
|
@ -207,7 +207,7 @@ public class BindConverterTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void fallsBackToApplicationConversionService() {
|
public void fallsBackToApplicationConversionService() {
|
||||||
BindConverter bindConverter = new BindConverter(new GenericConversionService(),
|
BindConverter bindConverter = BindConverter.get(new GenericConversionService(),
|
||||||
null);
|
null);
|
||||||
Duration result = bindConverter.convert("10s",
|
Duration result = bindConverter.convert("10s",
|
||||||
ResolvableType.forClass(Duration.class));
|
ResolvableType.forClass(Duration.class));
|
||||||
|
|
@ -216,14 +216,14 @@ public class BindConverterTests {
|
||||||
|
|
||||||
private BindConverter getPropertyEditorOnlyBindConverter(
|
private BindConverter getPropertyEditorOnlyBindConverter(
|
||||||
Consumer<PropertyEditorRegistry> propertyEditorInitializer) {
|
Consumer<PropertyEditorRegistry> propertyEditorInitializer) {
|
||||||
return new BindConverter(new ThrowingConversionService(),
|
return BindConverter.get(new ThrowingConversionService(),
|
||||||
propertyEditorInitializer);
|
propertyEditorInitializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BindConverter getBindConverter(Converter<?, ?> converter) {
|
private BindConverter getBindConverter(Converter<?, ?> converter) {
|
||||||
GenericConversionService conversionService = new GenericConversionService();
|
GenericConversionService conversionService = new GenericConversionService();
|
||||||
conversionService.addConverter(converter);
|
conversionService.addConverter(converter);
|
||||||
return new BindConverter(conversionService, null);
|
return BindConverter.get(conversionService, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerSampleTypeEditor(PropertyEditorRegistry registry) {
|
private void registerSampleTypeEditor(PropertyEditorRegistry registry) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue