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. C博客作业03——函数

    0.展示PTA总分 截图展示: 1.本章学习总结 1.1学习内容总结 (a)函数的定义 1)函数是一个完成特定工作的独立程序模块,包括库函数和自定义函数两种,scanf(),printf()等为库函数 ...

  2. Apache2 服务配置 ubuntu16.04 + django1.11

    (步骤) 环境 Ubuntu 16.04 Python 3.5.2 Django 1.11 Apache 2.4 1.Apache2安装 sudo apt-get install apache2 查看 ...

  3. Java为什么没有指针

    为了摒弃指针带来的风险(当然了,也就放弃了指针带来的效率). 1.C/C++为什么有指针? 这个很简单,程序都是在内存中运行的,只要有内存,就有内存地址,有地址,就必然有指针,只是C++对内存地址的访 ...

  4. 作业——09 安装关系型数据库MySQL 安装大数据处理框架Hadoop

    作业的要求来自于:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3161 简述Hadoop平台的起源.发展历史与应用现状. 起源: 2 ...

  5. 【大数据】分布式并行计算MapReduce

    作业来源于:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3319 1.  用自己的话阐明Hadoop平台上HDFS和MapReduc ...

  6. 【数值分析】Python实现Lagrange插值

    一直想把这几个插值公式用代码实现一下,今天闲着没事,尝试尝试. 先从最简单的拉格朗日插值开始!关于拉格朗日插值公式的基础知识就不赘述,百度上一搜一大堆. 基本思路是首先从文件读入给出的样本点,根据输入 ...

  7. [转]ProxmoxVE 干掉 VMware

    很久没有写这种通俗易懂的文章了,不是我愤世嫉俗,而是因为确实太为那些花大价钱购买VMware的冤大头鸣不平. 确实VMware在虚拟化市场占有率非常高,技术也非常成熟,用户使用起来很方便,但是如果你是 ...

  8. Python中为什么没有++和–(自增/减)(转)

    原文地址:http://blog.csdn.net/guang09080908/article/details/47273775(侵删) 这两天看了一些网上各大互联网公司的面试题,发现腾讯特别喜欢考察 ...

  9. net use命令详解(转)

    net use命令详解 1)建立空连接: net use \\IP\ipc$ "" /user:"" (一定要注意:这一行命令中包含了3个空格) 2)建立非空连 ...

  10. pytorch ImageFolder的覆写

    在为数据分类训练分类器的时候,比如猫狗分类时,我们经常会使用pytorch的ImageFolder: CLASS torchvision.datasets.ImageFolder(root, tran ...