如:
@Resource(name = "redisTemplate")
private HashOperations hash;
redisTemplate并不是HashOperations的实现类,这两个类在继承上也没任何关系。
原因就在于 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和HashOperations 没有继承关系或接口实现关系,那么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会去加载 HashOperations + Editor,即加载HashOperationsEditor这个类。且此类必须要继承PropertyEditorSupport或者实现PropertyEditor接口。
这个类非常简单,它重写了setValue方法,将RedisOperations中的opsForHash()返回值set进去,而opsForHash()返回值就是 DefaultHashOperations。
这样我们用editor get value的时候就能获取到DefaultHashOperations了。就可以将DefaultHashOperations注入到HashOperations 中去。