REDISTEMPLATE如何注入到VALUEOPERATIONS

今天看到Spring操作redis  是可以将redisTemplate注入到ValueOperations,避免了ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue(); 这样来获取ValueOperations;

@Resource(name = "redisTemplate")
private ValueOperations<String, Object> vOps;

redisTemplate并不是ValueOperations的实现类,这两个在继承上毫无联系的两个类是如何注入的呢。

后来查doGetBean()的代码才发现有一段以前没有详细的去看。

        // Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}

如果你要实例化的对象和你的引用对象并不是同一种类型,也就是如redisTemplate和ValueOperations一般不是父子关系或接口实现关系,那么spring就会进行转换。

用什么转换呢?Spring的editor。

String editorName = targetType.getName() + "Editor";
try {
Class<?> editorClass = cl.loadClass(editorName);
if (!PropertyEditor.class.isAssignableFrom(editorClass)) {
if (logger.isWarnEnabled()) {
logger.warn("Editor class [" + editorName +
"] does not implement [java.beans.PropertyEditor] interface");
}
unknownEditorTypes.add(targetType);
return null;
}
return (PropertyEditor) instantiateClass(editorClass);
}

spring会去加载 ValueOperations+Editor,即ValueOperationsEditor的类。且此类必须要实现PropertyEditor接口。

而我们在ValueOperations的包目录下确实会找到ValueOperationsEditor。

class ValueOperationsEditor extends PropertyEditorSupport {

    public void setValue(Object value) {
if (value instanceof RedisOperations) {
super.setValue(((RedisOperations) value).opsForValue());
} else {
throw new java.lang.IllegalArgumentException("Editor supports only conversion of type " + RedisOperations.class);
}
}
}

这个类非常简单,它重写了setValue方法,将redisTemplate中的opsForValue()返回值set进去,而opsForValue()返回值就是继承了ValueOperations的DefaultValueOperations。

这样我们用editor get value的时候就能获取到DefaultValueOperations了。就可以将DefaultValueOperations注入到ValueOperations中去了。

做个实验,写两个类

public class ClassA {
private String msg;
public ClassA(String msg){
this.msg=msg;
}
public void hi(){
System.out.println(msg);
}
}
@Component
public class ClassB {
public ClassA getA(){
return new ClassA("this is A from B");
}
}

类B有个方法可以获取A类实例,我们将此注入到A对象中。

public class EditorTest extends BaseJunitTest{

    @Resource(name="classB")
private ClassA a; @Test
public void test(){
a.hi();
}
}
BaseJunitTest配置了一些spring的XML配置文件 不需要管它。
此时我们还需要写一个ClassAEditor类。如果没有editor类的话当然会注入不了 并抛出一个异常
Bean named 'classB' is expected to be of type 'xxx.test.ClassA' but was actually of type 'xxx.test.ClassB'
我们完成ClassAEditor
public class ClassAEditor extends PropertyEditorSupport{
public void setValue(Object value) {
super.setValue(((ClassB)value).getA());
}
}

判断略去不写。

运行程序,得到正确结果

非常有意思的一个细节,工厂模式的一种体现。

 
 
分类: Spring

REDISTEMPLATE如何注入到VALUEOPERATIONS的更多相关文章

  1. springboot之使用redistemplate优雅地操作redis

    概述 本文内容主要 关于spring-redis 关于redis的key设计 redis的基本数据结构 介绍redis与springboot的整合 sringboot中的redistemplate的使 ...

  2. SpringBoot 使用RedisTemplate操作Redis

    新版: import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.T ...

  3. RedisTemplate操作Redis

    RedisTemplate Redis 可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为String(字符串).List(列表).Set(集合).Hash(散列)和 Zset(有序 ...

  4. redis之(二十一)redis之深入理解Spring Redis的使用

    关于spring redis框架的使用,网上的例子很多很多.但是在自己最近一段时间的使用中,发现这些教程都是入门教程,包括很多的使用方法,与spring redis丰富的api大相径庭,真是浪费了这么 ...

  5. 深入理解Spring Redis的使用 (一)、Spring Redis基本使用

    关于spring redis框架的使用,网上的例子很多很多.但是在自己最近一段时间的使用中,发现这些教程都是入门教程,包括很多的使用方法,与spring redis丰富的api大相径庭,真是浪费了这么 ...

  6. 分布式缓存技术redis学习—— 深入理解Spring Redis的使用

    关于spring redis框架的使用,网上的例子很多很多.但是在自己最近一段时间的使用中,发现这些教程都是入门教程,包括很多的使用方法,与spring redis丰富的api大相径庭,真是浪费了这么 ...

  7. spring boot整合redis

    1.项目目录结构 2.配置文件 application.yml testName: applicationName: testRedis spring: redis: host: 192.168.20 ...

  8. 使用Spring Boot搭建应用开发框架(一) —— 基础架构

    Spring的简史 第一阶段:XML配置,在Spring1.x时代,使用Spring开发满眼都是xml配置的Bean,随着项目的扩大,我们需要把xml配置文件分放到不同的配置文件里,那时候需要频繁的在 ...

  9. springboot~内嵌redis的使用

    对于单元测试来说,我们应该让它尽量保持单一环境,不要与网络资源相通讯,这样可以保证测试的稳定性与客观性,对于springboot这个框架来说,它集成了单元测试JUNIT,同时在设计项目时,你可以使用多 ...

随机推荐

  1. GoCN每日新闻(2019-10-03)

    GoCN每日新闻(2019-10-03) 国庆专辑:GopherChina祝大家国庆节快乐 GoCN每日新闻(2019-10-03) 1. 垃圾回收器如何监控你的应用程序 https://medium ...

  2. epoll 或者 kqueue 的原理是什么?

    来自知乎:http://www.zhihu.com/question/20122137 epoll 或者 kqueue 的原理是什么? 为什么epoll和kqueue可以用基于事件的方式,单线程的实现 ...

  3. python问题集

    1.selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to be in P ...

  4. 对象与json字符串转换类设计

    public static class JsonNewtonsoft { /// <summary> /// 把对象转换为JSON字符串 /// </summary> /// ...

  5. SpringBoot MAVEN编译报错Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:

    参考了好几篇文章没搞定,直到查询错误关键字 An unknown compilation problem occurred 分别参考了以下博客: https://blog.csdn.net/fanre ...

  6. 初进python世界之数据类型

    文章来源: https://www.cnblogs.com/seagullunix/articles/7297946.html 基本运算符 常用数据类型: 字符串(Str) 数字(Digit) 列表( ...

  7. golang高级用法总结

    sync.WaitGroup add()  done()  wait() 相当于计数器,done会减一,wait会等待所有线程都执行完才执行下面代码 sync.pool 用来封装连接池

  8. 什么是 Web server

    前端开发人员应该对 Web 开发中的基本概念有一些了解,请简述 什么是 Web 服务器 Web 服务器能做什么 首先我们来了解什么是服务器(server) 一般来说,server 有两重意思 有时候 ...

  9. 【计算机视觉】目标检测中的指标衡量Recall与Precision

    [计算机视觉]目标检测中的指标衡量Recall与Precision 标签(空格分隔): [图像处理] 说明:目标检测性能指标Recall与Precision的理解. Recall与Precision ...

  10. C/c++语言开源项目总结

    值得学习的C语言开源项目 -1. Webbench Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性 ...