Introduce ConfigurableConversionService interface

Consolidates ConversionService and ConverterRegistry interfaces;
implemented by GenericConversionService.

ConfigurablePropertyResolver#getConversionService now returns this
new type (hence so too does
ConfigurableEnvironment#getConversionService). This allows for
convenient addition / removal of Converter instances from Environment's
existing ConversionService.  For example:

    ConfigurableApplicationContext ctx = new ...
    ConfigurableEnvironment env = ctx.getEnvironment();
    env.getConversionService().addConverter(new FooConverter());

Issue: SPR-8389
This commit is contained in:
Chris Beams 2011-06-02 06:50:42 +00:00
parent 6ae04eb7e6
commit 8227cb6243
5 changed files with 71 additions and 18 deletions

View File

@ -0,0 +1,39 @@
/*
* Copyright 2002-2011 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.convert.support;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.ConverterRegistry;
/**
* Configuration interface to be implemented by most if not all {@link ConversionService}
* types. Consolidates the read-only operations exposed by {@link ConversionService} and
* the mutating operations of {@link ConverterRegistry} to allow for convenient ad-hoc
* addition and removal of {@link org.springframework.core.convert.converter.Converter
* Converters} through. The latter is particularly useful when working against a
* {@link org.springframework.core.env.ConfigurableEnvironment ConfigurableEnvironment}
* instance in application context bootstrapping code.
*
* @author Chris Beams
* @since 3.1
* @see org.springframework.core.env.ConfigurablePropertyResolver#getConversionService()
* @see org.springframework.core.env.ConfigurableEnvironment
* @see org.springframework.context.ConfigurableApplicationContext#getEnvironment()
*/
public interface ConfigurableConversionService extends ConversionService, ConverterRegistry {
}

View File

@ -47,13 +47,15 @@ import org.springframework.util.ClassUtils;
/**
* Base {@link ConversionService} implementation suitable for use in most environments.
* Implements {@link ConverterRegistry} as registration API.
* Indirectly implements {@link ConverterRegistry} as registration API through the
* {@link ConfigurableConversionService} interface.
*
* @author Keith Donald
* @author Juergen Hoeller
* @author Chris Beams
* @since 3.0
*/
public class GenericConversionService implements ConversionService, ConverterRegistry {
public class GenericConversionService implements ConfigurableConversionService {
private static final GenericConverter NO_OP_CONVERTER = new GenericConverter() {
public Set<ConvertiblePair> getConvertibleTypes() {

View File

@ -29,7 +29,7 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.ConfigurableConversionService;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@ -356,11 +356,11 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
return this.propertyResolver.resolveRequiredPlaceholders(text);
}
public void setConversionService(ConversionService conversionService) {
public void setConversionService(ConfigurableConversionService conversionService) {
this.propertyResolver.setConversionService(conversionService);
}
public ConversionService getConversionService() {
public ConfigurableConversionService getConversionService() {
return this.propertyResolver.getConversionService();
}

View File

@ -26,7 +26,7 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.ConfigurableConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.util.PropertyPlaceholderHelper;
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver;
@ -41,7 +41,7 @@ public abstract class AbstractPropertyResolver implements ConfigurablePropertyRe
protected final Log logger = LogFactory.getLog(getClass());
protected ConversionService conversionService = new DefaultConversionService();
protected ConfigurableConversionService conversionService = new DefaultConversionService();
private PropertyPlaceholderHelper nonStrictHelper;
private PropertyPlaceholderHelper strictHelper;
@ -52,11 +52,11 @@ public abstract class AbstractPropertyResolver implements ConfigurablePropertyRe
private final Set<String> requiredProperties = new LinkedHashSet<String>();
public ConversionService getConversionService() {
public ConfigurableConversionService getConversionService() {
return this.conversionService;
}
public void setConversionService(ConversionService conversionService) {
public void setConversionService(ConfigurableConversionService conversionService) {
this.conversionService = conversionService;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@ -16,14 +16,13 @@
package org.springframework.core.env;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.ConfigurableConversionService;
/**
* Configuration interface to be implemented by most if not all {@link PropertyResolver
* PropertyResolvers}. Provides facilities for accessing and customizing the
* {@link ConversionService} used when converting property values from one type to
* another.
* {@link org.springframework.core.convert.ConversionService ConversionService} used when
* converting property values from one type to another.
*
* @author Chris Beams
* @since 3.1
@ -31,18 +30,31 @@ import org.springframework.core.convert.ConversionService;
public interface ConfigurablePropertyResolver extends PropertyResolver {
/**
* @return the {@link ConversionService} used when performing type
* @return the {@link ConfigurableConversionService} used when performing type
* conversions on properties.
* <p>The configurable nature of the returned conversion service allows for
* the convenient addition and removal of individual {@code Converter} instances:
* <pre class="code">
* ConfigurableConversionService cs = env.getConversionService();
* cs.addConverter(new FooConverter());
* </pre>
* @see PropertyResolver#getProperty(String, Class)
* @see org.springframework.core.convert.converter.ConverterRegistry#addConverter
*/
ConversionService getConversionService();
ConfigurableConversionService getConversionService();
/**
* Set the {@link ConversionService} to be used when performing type
* Set the {@link ConfigurableConversionService} to be used when performing type
* conversions on properties.
* <p><strong>Note:</strong> as an alternative to fully replacing the {@code
* ConversionService}, consider adding or removing individual {@code Converter}
* intstances by drilling into {@link #getConversionService()} and calling methods
* such as {@code #addConverter}.
* @see PropertyResolver#getProperty(String, Class)
* @see #getConversionService()
* @see org.springframework.core.convert.converter.ConverterRegistry#addConverter
*/
void setConversionService(ConversionService conversionService);
void setConversionService(ConfigurableConversionService conversionService);
/**
* Set the prefix that placeholders replaced by this resolver must begin with.