一、redisTemplate是怎么注入给hashOperations的
先看一段代码:
@Resource(name="redisTemplate")
private HashOperations<String, String, Object> hashOperations;
HashOperations 和 RedisTemplate 并不存在继承关系,为什么可以注入呢?这个就是spring的editor机制。
这个转换,主要是在 org.springframework.data.redis.core.HashOperationsEditor 这个类中进行的。源码:
class HashOperationsEditor extends PropertyEditorSupport {
public void setValue(Object value) {
if (value instanceof RedisOperations) {
super.setValue(((RedisOperations) value).opsForHash());
} else {
throw new java.lang.IllegalArgumentException("Editor supports only conversion of type " + RedisOperations.class);
}
}
}
可以看到,在 setValue 中,将 redisTemplate.opsForHash() 赋值给这个value,也就是相当于:
hashOperations = redisTemplate.opsForHash();
二、注入流程是怎么发生的
从这个图可以看出来,先是执行 createBean 创建实体类,然后populateBean,在postProcessorPropertyValues 中进行属性注入,给 hashOperations 赋值。
通过 一系列调用,
getResource() -> autowireResrouce() -> getBean() -> doGetBean() -> convertIfNecessary() -> doConvert() -> convertIfNecessary() -> convertIfNecessary() -> doConvertValue() -> setValue()
最终执行HashOperationsEditor 中的 setValue方法,进行一个赋值。
其中,在倒数第一个的convertIfNecessary() 方法中,通过classType来找到需要的editor方法:
public <T> T convertIfNecessary(String propertyName, Object oldValue, Object newValue,
Class<T> requiredType, TypeDescriptor typeDescriptor) throws IllegalArgumentException {
// Custom editor for this type?
PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName);
...
}
类 PropertyEditorRegistrySupport 实现了接口 PropertyEditorRegistry,并将所有的 自定义 Editors 保存在 map 结构的变量 customEditors 中。
public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
private Map<Class<?>, PropertyEditor> customEditors;
...
private PropertyEditor getCustomEditor(Class<?> requiredType) {
if (requiredType == null || this.customEditors == null) {
return null;
}
// Check directly registered editor for type.
PropertyEditor editor = this.customEditors.get(requiredType);
if (editor == null) {
...
}
return editor;
}
}
done.