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. CF830E Perpetual Motion Machine

    题面 题解 神仙构造题. 分五种情况考虑: 如果存在一个环,那么令环上的点权值为\(1\),其余点权值为\(0\). 如果存在一个度数大于\(3\)的点,令这个点的权值为\(2\),和它相邻的点权值为 ...

  2. 第07组 Beta冲刺(1/5)

    队名:摇光 队长:杨明哲 组长博客:求戳 作业博客:求再戳 队长:杨明哲 过去两天完成了哪些任务 文字/口头描述:代码编辑器 展示GitHub当日代码/文档签入记录:(组内共用,已询问过助教小姐姐) ...

  3. 剑指offer:字符流中第一个不重复的字符

    题目描述: 请实现一个函数用来找出字符流中第一个只出现一次的字符.例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g".当从该字符流中读 ...

  4. 2019年10~11月-NLP工程师求职记录

    求职目标:NLP工程师 为什么想换工作? 除了技术相关书籍,我没读过太多其他类型的书,其中有一本内容短但是对我影响特别大的书--<谁动了我的奶酪>.出门问问是我毕业后的第一份工作,无论是工 ...

  5. Solidity truffle,部署合约到Ropsten测试链或主链,调用合约(转)

    Solidity truffle,部署合约到Ropsten测试链或主链,调用合约 转 https://blog.csdn.net/houyanhua1/article/details/89010896 ...

  6. odoo开发笔记--定时任务源码分析

    场景描述: 处理思路: 参考文章: 定时任务相关: https://www.jianshu.com/p/ad48239f84d6 https://blog.csdn.net/M0relia/artic ...

  7. Python之内置装饰器property

    # -*- coding: utf-8 -*- # author:baoshan class Student(object): def __init__(self, name): self.name ...

  8. Python3基础 yield next 获取生成器生出的值

             Python : 3.7.3          OS : Ubuntu 18.04.2 LTS         IDE : pycharm-community-2019.1.3    ...

  9. SSM框架新特性关于用Java配置类完全代替XML

    项目目录结构 从Spring3.0,@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法, 这些方法将会被AnnotationConf ...

  10. python路径相关技巧

    在文件C:\work\python\rqalpha\rqalpha\utils\config.py 找文件:C:\work\python\rqalpha\rqalpha\config.yml 则通过下 ...