@Resouce注入无继承和实现关系的实例

文章参考了https://www.cnblogs.com/tangyuanyuan/p/8067923.html

问题

最近看redis教程过程中,发现了直接将redisTemplate注入到ValueOperations,进行两个无关联类之间的注入的方式,甚是不解,遂百度。

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

原理

原来在spring注入对象时,会进行判断。
如果你要实例化的对象和你的引用对象并不是同一种类型,也就是像redisTemplate和ValueOperations这样没有继承关系或接口实现关系,那么spring就会进行转换。

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

用什么转换呢?Spring的editor,spring会去加载 ValueOperations+Editor,即ValueOperationsEditor的类。且此类必须要实现PropertyEditor接口。

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

 

而在ValueOperations的包目录下确实会找到ValueOperationsEditor,该类继承的PropertyEditorSupport 类实现了PropertyEditor接口。

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 getValue的时候就能获取到DefaultValueOperations了。就可以将DefaultValueOperations注入到ValueOperations中去了。

总结

也就是说,如果想实现无关联类之间的注入,需要为被注入的类写一个Editor类,并实现PropertyEditor接口,重写setValue方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值