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 可以被自动发现 。
文章插图
可以看到 , ListOperations 类和 ListOperationsEditor 都在 org.springframework.data.redis.core 包下 , 且 ListOperationsEditor 符合命名规则 , 即在 ListOperations 类名上加上 Editor 后缀 , 所以可以自动发现并生效 。
那么redis这个疑问是得到回答了 , 但是刚才尝试的构造方法注入其实也可以 , 那么具体spring用的哪个逻辑呢?
于是debug源码吧 , 看看具体逻辑:
之前的寻找的就忽略不提了 , 直接上重点 。
文章插图
文章插图
可以看到是请求到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调用的上层 。
文章插图
推荐阅读
- 疑似华为P50谍照曝光:后摄模组很是奇特
- 基于Spring+Angular9+MySQL开发平台
- 西安各区县举办多类型活动 抢抓区域科技创新发展高地
- HFL Redis_10_set类型底层存储数据结构
- 一个奇特故障带来的诡异电脑问题
- 别不拿GateWay当回事,SpringCloud告诉你错了
- web 安全之 Spring Security 入门教程
- Spring Application实例化流程和构造方法参数
- SpringBoot常用注解
- 阿里爆款SpringBoot项目实战PDF+源码+视频分享