zoukankan      html  css  js  c++  java
  • spring 之 类型转换 2

    spring内置的转换器

    在spring xml 文件中,配置属性的时候, 不管实际是 list 还是map ,还是Date, 或者原生的java 类型, 我们只能配置xml 给它们。 那么 spring 在实例化bean 的时候, 这些属性是必须要经过转换的。 那么,spring 具体是怎么实现的呢?

    答案就是:

    public class DefaultConversionService extends GenericConversionService {
        private static final boolean javaUtilOptionalClassAvailable = ClassUtils.isPresent("java.util.Optional", DefaultConversionService.class.getClassLoader());
        private static final boolean jsr310Available = ClassUtils.isPresent("java.time.ZoneId", DefaultConversionService.class.getClassLoader());
        private static final boolean streamAvailable = ClassUtils.isPresent("java.util.stream.Stream", DefaultConversionService.class.getClassLoader());
        private static volatile DefaultConversionService sharedInstance;
    
        public static ConversionService getSharedInstance() {
            if(sharedInstance == null) {
                Class var0 = DefaultConversionService.class;
                synchronized(DefaultConversionService.class) {
                    if(sharedInstance == null) {
                        sharedInstance = new DefaultConversionService();
                    }
                }
            }
    
            return sharedInstance;
        }
    
        public DefaultConversionService() {
            addDefaultConverters(this);
        }
    
        public static void addDefaultConverters(ConverterRegistry converterRegistry) {
            addScalarConverters(converterRegistry); // 注册 标量的转换器, 也就是把xml配置文件中 字面值 转换为 常见的简单的普通类型 
            addCollectionConverters(converterRegistry);  // 转换为 集合
            converterRegistry.addConverter(new ByteBufferConverter((ConversionService)converterRegistry));
            if(jsr310Available) {
                DefaultConversionService.Jsr310ConverterRegistrar.registerJsr310Converters(converterRegistry);
            }
    
            converterRegistry.addConverter(new ObjectToObjectConverter());
            converterRegistry.addConverter(new IdToEntityConverter((ConversionService)converterRegistry));
            converterRegistry.addConverter(new FallbackObjectToStringConverter());
            if(javaUtilOptionalClassAvailable) {
                converterRegistry.addConverter(new ObjectToOptionalConverter((ConversionService)converterRegistry));
            }
    
        }
    
        public static void addCollectionConverters(ConverterRegistry converterRegistry) {
            ConversionService conversionService = (ConversionService)converterRegistry;
            converterRegistry.addConverter(new ArrayToCollectionConverter(conversionService));
            converterRegistry.addConverter(new CollectionToArrayConverter(conversionService));
            converterRegistry.addConverter(new ArrayToArrayConverter(conversionService));
            converterRegistry.addConverter(new CollectionToCollectionConverter(conversionService));
            converterRegistry.addConverter(new MapToMapConverter(conversionService));
            converterRegistry.addConverter(new ArrayToStringConverter(conversionService));
            converterRegistry.addConverter(new StringToArrayConverter(conversionService));
            converterRegistry.addConverter(new ArrayToObjectConverter(conversionService));
            converterRegistry.addConverter(new ObjectToArrayConverter(conversionService));
            converterRegistry.addConverter(new CollectionToStringConverter(conversionService));
            converterRegistry.addConverter(new StringToCollectionConverter(conversionService));
            converterRegistry.addConverter(new CollectionToObjectConverter(conversionService));
            converterRegistry.addConverter(new ObjectToCollectionConverter(conversionService));
            if(streamAvailable) {
                converterRegistry.addConverter(new StreamConverter(conversionService));
            }
    
        }
    
        private static void addScalarConverters(ConverterRegistry converterRegistry) {
            converterRegistry.addConverterFactory(new NumberToNumberConverterFactory());
            converterRegistry.addConverterFactory(new StringToNumberConverterFactory());
            converterRegistry.addConverter(Number.class, String.class, new ObjectToStringConverter());
            converterRegistry.addConverter(new StringToCharacterConverter());
            converterRegistry.addConverter(Character.class, String.class, new ObjectToStringConverter());
            converterRegistry.addConverter(new NumberToCharacterConverter());
            converterRegistry.addConverterFactory(new CharacterToNumberFactory());
            converterRegistry.addConverter(new StringToBooleanConverter());
            converterRegistry.addConverter(Boolean.class, String.class, new ObjectToStringConverter());
            converterRegistry.addConverterFactory(new StringToEnumConverterFactory());
            converterRegistry.addConverter(new EnumToStringConverter((ConversionService)converterRegistry));
            converterRegistry.addConverterFactory(new IntegerToEnumConverterFactory());
            converterRegistry.addConverter(new EnumToIntegerConverter((ConversionService)converterRegistry));
            converterRegistry.addConverter(new StringToLocaleConverter());
            converterRegistry.addConverter(Locale.class, String.class, new ObjectToStringConverter());
            converterRegistry.addConverter(new StringToCharsetConverter());
            converterRegistry.addConverter(Charset.class, String.class, new ObjectToStringConverter());
            converterRegistry.addConverter(new StringToCurrencyConverter());
            converterRegistry.addConverter(Currency.class, String.class, new ObjectToStringConverter());
            converterRegistry.addConverter(new StringToPropertiesConverter());
            converterRegistry.addConverter(new PropertiesToStringConverter());
            converterRegistry.addConverter(new StringToUUIDConverter());
            converterRegistry.addConverter(UUID.class, String.class, new ObjectToStringConverter());
        }
    
        private static final class Jsr310ConverterRegistrar {
            private Jsr310ConverterRegistrar() {
            }
    
            public static void registerJsr310Converters(ConverterRegistry converterRegistry) {
                converterRegistry.addConverter(new StringToTimeZoneConverter());
                converterRegistry.addConverter(new ZoneIdToTimeZoneConverter());
                converterRegistry.addConverter(new ZonedDateTimeToCalendarConverter());
            }
        }
    }

    大致的堆栈是:

    at org.springframework.core.convert.support.StringToNumberConverterFactory$StringToNumber.convert(StringToNumberConverterFactory.java:59)
    at org.springframework.core.convert.support.StringToNumberConverterFactory$StringToNumber.convert(StringToNumberConverterFactory.java:49)
    at org.springframework.core.convert.support.GenericConversionService$ConverterFactoryAdapter.convert(GenericConversionService.java:436)
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:37)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:203)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:173)
    at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:576)
    at org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:603)
    at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:216)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1538)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1497)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1237)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:552)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    - locked <0x677> (a java.util.concurrent.ConcurrentHashMap)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)

    spring xml中常见属性的注入:

    注入array 或者list 有两种方式:

    1 直接使用 <value>, 每个 item 使用 逗号分隔, 这个时候使用的是 StringToCollectionConverter

    如: 

    <property name="strArr">
    <value>aaa,bbb,ccc</value>
    </property>

    2 使用 <list> 子标签, (别看名字是 list, 但它可以转换list 和 array; spring 并没有单独对 数组即 array 进行转换, 而是把list/array 统一为 list 了) 。但是实际处理的时候是区分开了的, array 使用的是 ArrayToArrayConverter, list 使用的是CollectionToCollectionConverter  。 

    <property name="strArr">
    <list>
    <value>  // list 下面每个 value 是一个item
    AAA
    </value>
    <value>
    BBB
    </value>
    <value>
    CCC
    </value>
    </list>

    </property>

    注入Set 有两种方式:

    同样, 注入set 也有两种方式: 
    1 使用 <value> , 和数组或list相同, 这个时候使用的是
    StringToCollectionConverter
    2 或者使用 <set> 标签 ,
    对应 set 使用的和数组和list相同: CollectionToCollectionConverter ;
    <property name="aSet">
    <set><value>aaa</value><value>bbb</value></set>
    </property>

    注入Map 或者 Properties:

    而,  对于map 或者 properties 的注入, 可以使用<map> 或者 <props> ( 因为他们是可以相互转换的). 对应的 都 是MapToMapConverter 
    <property name="strMap">
    <props>
    <prop key="k1">V1</prop>
    <prop key="k2">V2</prop>
    </props>
    </property>
    <property name="strProp">
    <map>
    <entry key="aa" value="AA"></entry>
    <entry key="bb" value="BB"></entry>
    </map>
    </property>
    另外, 对于 properties, 我们还可以使用 value 直接注入, 它实际使用的转换器是:StringToPropertiesConverter
    格式是, 每行一个 entry,  用 = 分隔 kv : 
    <property name="strProp">
    <value>
    aa = aa
    bb = BB
    </value>
    </property>

    但是map 不能这样注入。 因为并不存在 StringToMapConverter
  • 相关阅读:
    图片上传 多张
    ES6的新特性
    css超出一行添加省略号属性:text-overflow和white-space
    JQuery 中 is(':visible') 解析及用法
    Git详解之Git分支
    jQuery选择器和选取方法
    git命令之git remote的用法
    运算符中的一些小技巧
    Git 忽略一些文件不加入版本控制
    git 查看远程分支、本地分支、创建分支、把分支推到远程repository、删除本地分支
  • 原文地址:https://www.cnblogs.com/FlyAway2013/p/7856764.html
Copyright © 2011-2022 走看看