Share BinderConversionService with a static

Use a single shared static `BinderConversionService` instance for all
created binders to save memory and improve performance.

Fixes gh-11352
pull/11365/merge
Phillip Webb 7 years ago
parent 6cb331ed2c
commit e141f77801

@ -351,8 +351,8 @@ public class Binder {
* @return a {@link Binder} instance * @return a {@link Binder} instance
*/ */
public static Binder get(Environment environment) { public static Binder get(Environment environment) {
return new Binder(ConfigurationPropertySources.get(environment), return new Binder(ConfigurationPropertySources
new PropertySourcesPlaceholdersResolver(environment)); .get(environment), new PropertySourcesPlaceholdersResolver(environment));
} }
/** /**

@ -38,9 +38,11 @@ import org.springframework.format.support.DefaultFormattingConversionService;
*/ */
public class BinderConversionService implements ConversionService { public class BinderConversionService implements ConversionService {
private final ConversionService conversionService; private static final ConversionService additionalConversionService = createAdditionalConversionService();
private static final ConversionService defaultConversionService = new DefaultFormattingConversionService();
private final ConversionService additionalConversionService; private final ConversionService conversionService;
/** /**
* Create a new {@link BinderConversionService} instance. * Create a new {@link BinderConversionService} instance.
@ -48,22 +50,21 @@ public class BinderConversionService implements ConversionService {
*/ */
public BinderConversionService(ConversionService conversionService) { public BinderConversionService(ConversionService conversionService) {
this.conversionService = (conversionService != null ? conversionService this.conversionService = (conversionService != null ? conversionService
: new DefaultFormattingConversionService()); : defaultConversionService);
this.additionalConversionService = createAdditionalConversionService();
} }
@Override @Override
public boolean canConvert(Class<?> sourceType, Class<?> targetType) { public boolean canConvert(Class<?> sourceType, Class<?> targetType) {
return (this.conversionService != null return (this.conversionService != null
&& this.conversionService.canConvert(sourceType, targetType)) && this.conversionService.canConvert(sourceType, targetType))
|| this.additionalConversionService.canConvert(sourceType, targetType); || additionalConversionService.canConvert(sourceType, targetType);
} }
@Override @Override
public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) { public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) {
return (this.conversionService != null return (this.conversionService != null
&& this.conversionService.canConvert(sourceType, targetType)) && this.conversionService.canConvert(sourceType, targetType))
|| this.additionalConversionService.canConvert(sourceType, targetType); || additionalConversionService.canConvert(sourceType, targetType);
} }
@Override @Override
@ -92,7 +93,7 @@ public class BinderConversionService implements ConversionService {
private <T> T callAdditionalConversionService(Function<ConversionService, T> call, private <T> T callAdditionalConversionService(Function<ConversionService, T> call,
RuntimeException cause) { RuntimeException cause) {
try { try {
return call.apply(this.additionalConversionService); return call.apply(additionalConversionService);
} }
catch (ConverterNotFoundException ex) { catch (ConverterNotFoundException ex) {
throw (cause != null ? cause : ex); throw (cause != null ? cause : ex);

Loading…
Cancel
Save