博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
redisTemplate如何注入到ValueOperations
阅读量:4980 次
发布时间:2019-06-12

本文共 3366 字,大约阅读时间需要 11 分钟。

 

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

@Resource(name = "redisTemplate")private ValueOperations
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);    }}

 

@Componentpublic 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());      }}
 

判断略去不写。

运行程序,得到正确结果

 

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

 

 

转载于:https://www.cnblogs.com/tangyuanyuan/p/8067923.html

你可能感兴趣的文章
索引和索引调整向导
查看>>
linux下的rz sz
查看>>
openfire 学习笔记--转自网易博客
查看>>
编译(树形DP)
查看>>
java微信支付异步回调接收参数
查看>>
test
查看>>
关于Debug certificate expired的问题
查看>>
移动端浏览器有哪些,内核分别是什么
查看>>
利用python实现简单随机验证码
查看>>
ExtJs4 笔记 Ext.Panel 面板控件、 Ext.window.Window 窗口控件、 Ext.container.Viewport 布局控件...
查看>>
Django框架—ORM操作笔记
查看>>
FireDAC如何连接ORACLE数据库
查看>>
(转)logback配置详解
查看>>
解决电脑系统卡、慢 3分钟成为高手!
查看>>
9. Palindrome Number
查看>>
52. N-Queens II
查看>>
ORA-01555错误总结(二)
查看>>
flask简单demo
查看>>
SSH
查看>>
卷积神经网络—第一周
查看>>