Spring 奇特的类型转化( 二 )


class ListOperationsEditor extends PropertyEditorSupport { public void setValue(Object value) {if (value instanceof RedisOperations) {super.setValue(((RedisOperations) value).opsForList());} else {throw new IllegalArgumentException("Editor supports only conversion of type " + RedisOperations.class);} }}如果 PropertyEditor 类与它们处理的类在同一个包中 , 并且类名再加上 Editor 后缀 , 则无需显式注册 , 该 PropertyEditor 可以被自动发现 。
Spring 奇特的类型转化文章插图
可以看到 , ListOperations 类和 ListOperationsEditor 都在 org.springframework.data.redis.core 包下 , 且 ListOperationsEditor 符合命名规则 , 即在 ListOperations 类名上加上 Editor 后缀 , 所以可以自动发现并生效 。
那么redis这个疑问是得到回答了 , 但是刚才尝试的构造方法注入其实也可以 , 那么具体spring用的哪个逻辑呢?
于是debug源码吧 , 看看具体逻辑:
之前的寻找的就忽略不提了 , 直接上重点 。
Spring 奇特的类型转化文章插图
Spring 奇特的类型转化文章插图
可以看到是请求到ConversionUtils 是转换工具类 , 之后执行converter.convert方法 。
public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {if (source == null) {return null;}Class sourceClass = sourceType.getType();Class targetClass = targetType.getType();Member member = getValidatedMember(targetClass, sourceClass);try {if (member instanceof Method) {Method method = (Method) member;ReflectionUtils.makeAccessible(method);if (!Modifier.isStatic(method.getModifiers())) {return method.invoke(source);}else {return method.invoke(null, source);}}else if (member instanceof Constructor) {Constructor ctor = (Constructor) member;ReflectionUtils.makeAccessible(ctor);return ctor.newInstance(source);}}catch (InvocationTargetException ex) {throw new ConversionFailedException(sourceType, targetType, source, ex.getTargetException());}catch (Throwable ex) {throw new ConversionFailedException(sourceType, targetType, source, ex);}// If sourceClass is Number and targetClass is Integer, the following message should expand to:// No toInteger() method exists on java.lang.Number, and no static valueOf/of/from(java.lang.Number)// method or Integer(java.lang.Number) constructor exists on java.lang.Integer.throw new IllegalStateException(String.format("No to%3$s() method exists on %1$s, " +"and no static valueOf/of/from(%1$s) method or %3$s(%1$s) constructor exists on %2$s.",sourceClass.getName(), targetClass.getName(), targetClass.getSimpleName())); }可以看到转换类会通过构造方法Constructor去创建目标class的对象 , 也就是说这时候Test1的对象新创建的 , 这时候就看Resource注解对应获取对象单例如何实现了 , 这次就不说了 , 直接说结果 , 是会删除本地cache , 以最后生成的为主 。
那么知道构造如何处理的 , PropertyEditor怎么使用的呢 , 那就是在ConversionUtils调用的上层 。
Spring 奇特的类型转化文章插图


推荐阅读