弹簧双向转换器

mak*_*aks 4 java spring-3

Spring 3具有类型转换这样一个很好的功能.它提供了一个转换器SPI(Converter<S, T>),用于实现差分转换逻辑.Converter类型的子类允许定义单向转换(仅从S到T),因此如果我还希望从T到SI执行转换,则需要定义另一个实现的转换器类Converter<T, S>.如果我有许多可以转换的类,我需要定义许多转换器.是否有可能在一个转换器中定义双向转换逻辑(从S到T和从T到S)?以及它将如何使用?

PS.现在我通过ConversionServiceFactoryBean在配置文件中定义/注入它们来使用我的转换器

Bar*_*man 11

你是对的,如果你想org.springframework.core.convert.converter.Converter直接使用界面,你需要实现两个转换器,每个方向一个.

但是春天3还有其他两个选择:

  1. 如果您的转换不是对象到对象,而是对象到字符串(和返回),那么您可以实现转换org.springframework.format.Formatter.格式化程序注册为GenericConverters(请参阅http://static.springsource.org/spring-webflow/docs/2.3.x/reference/html/ch05s07.html#converter-upgrade-to-spring-3)

  2. 否则,您可以实现自己的org.springframework.core.convert.converter.GenericConverter,这使得使用反射创建TwoWayConverter实现变得容易.

    public abstract class AbstractTwoWayConverter<S, T> implements GenericConverter {
    
        private Class<S> classOfS;
        private Class<T> classOfT;
    
        protected AbstractTwoWayConverter() {
            Type typeA = ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
            Type typeB = ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
            this.classOfS = (Class) typeA;
            this.classOfT = (Class) typeB;
        }
    
        public Set<ConvertiblePair> getConvertibleTypes() {
            Set<ConvertiblePair> convertiblePairs = new HashSet<ConvertiblePair>();
            convertiblePairs.add(new ConvertiblePair(classOfS, classOfT));
            convertiblePairs.add(new ConvertiblePair(classOfT, classOfS));
            return convertiblePairs;
        }
    
        public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
            if (classOfS.equals(sourceType.getType())) {
                return this.convert((S) source);
            } else {
                return this.convertBack((T) source);
            }
        }
    
        protected abstract T convert(S source);
    
        protected abstract S convertBack(T target);
    
    }
    
    /** 
     * converter to convert between a userId and user.
     * this class can be registered like so: 
     * conversionService.addConverter(new UserIdConverter (userDao));
     */ 
    public class UserIdConverter extends AbstractTwoWayConverter<String, User> {
    
        private final UserDao userDao;
    
        @Autowired
        public UserIdConverter(UserDao userDao) {
            this.userDao = userDao;
        }
    
        @Override
        protected User convert(String userId) {
            return userDao.load(userId);
        }
    
        @Override
        protected String convertBack(User target) {
            return target.getUserId();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)