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

判断略去不写。

运行程序,得到正确结果

 

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

 

 

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 中的 RedisTemplate 是一个用于操作 Redis 数据库的高级模板。它提供了一组方法,可以方便地执行常见的 Redis 操作,如存储、检索和删除数据。 使用 RedisTemplate 需要先配置 Redis 的连接信息,包括主机、端口、密码等。可以通过在 application.properties(或 application.yml)文件中设置相应的属性来配置 Redis 连接信息。 接下来,可以通过自动装配的方式将 RedisTemplate 注入到需要使用 Redis中。然后就可以使用 RedisTemplate 的方法来执行对应的 Redis 操作了,比如: - 存储数据:可以使用 opsForValue() 方法来获取 ValueOperations 对象,然后通过 set() 方法存储键值对。 - 检索数据:可以使用 opsForValue() 方法来获取 ValueOperations 对象,然后通过 get() 方法检索键对应的值。 - 删除数据:可以使用 delete() 方法删除指定的键。 除了上述常见操作外,RedisTemplate 还提供了其他一些方法,例如对列表、集合、有序集合等数据结构进行操作的方法。 需要注意的是,RedisTemplate 是一个泛型,可以通过设置泛型参数来指定键和值的型。默认情况下,键和值都被序列化为字节数组进行存储,但也可以自定义序列化器来支持其他型的对象。 总之,RedisTemplate 提供了一种方便、简洁的方式来操作 Redis 数据库,使得在 Spring Boot 项目中使用 Redis 变得更加容易和高效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值