关于@Resource(name = “redisTemplate”)注入问题

依赖dependencies


    org.springframework.boot
    spring-boot-starter


    org.springframework.boot
    spring-boot-starter-data-redis


    org.apache.commons
    commons-pool2




    org.springframework.boot
    spring-boot-starter-test
    test
    
        
            org.junit.vintage
            junit-vintage-engine
        
    




    com.fasterxml.jackson.core
    jackson-databind




    org.springframework.boot
    spring-boot-starter-jdbc


    mysql
    mysql-connector-java


解决

1.关于 @Resource(name = “redisTemplate”) 为何可以为 ValueOperations 类型注入实体

@Autowired
private RedisTemplate redisTemplate;

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

可以延伸为实例化的对象和你的引用对象并不是同一种类型的问题。也就是如redisTemplate和ValueOperations一般不是父子关系或接口实现关系,那么spring就会进行转换。转换的方式就是通过Spring的Editor做的。
在项目启动过程中,spring会进行实例化和注入操作
在org.springframework.beans.factory.support.AbstractBeanFactory 类中的 doGetBean 方法中,实际上是调用了 org.springframework.beans.TypeConverterDelegate 类中convertIfNecessary方法,待进入以下步骤来处理实例化类型与引用类型不同的问题

// Value not of required type?
if (editor != null || (requiredType != null && !ClassUtils.isAssignableValue(requiredType, convertedValue))) {
     
	if (typeDescriptor != null && requiredType != null && Collection.class.isAssignableFrom(requiredType) &&
			convertedValue instanceof String) {
     
		TypeDescriptor elementTypeDesc = typeDescriptor.getElementTypeDescriptor();
		if (elementTypeDesc != null) {
     
			Class<?> elementType = elementTypeDesc.getType();
			if (Class.class == elementType || Enum.class.isAssignableFrom(elementType)) {
     
				convertedValue = StringUtils.commaDelimitedListToStringArray((String) convertedValue);
			}
		}
	}
	if (editor == null) {
     
	//此处去获取相关Editor,在该问题中为ValueOperationsEditor类
		editor = findDefaultEditor(requiredType);
	}
	convertedValue = doConvertValue(oldValue, convertedValue, requiredType, editor);
}

findDefaultEditor方法是获取相关Editor,在该问题中为ValueOperationsEditor的类。且此类必须要实现PropertyEditor接口。

doConvertValue的作用

Object convertedValue = newValue;
if (editor != null && !(convertedValue instanceof String)) {
     
	try {
     
		editor.setValue(convertedValue);
		Object newConvertedValue = editor.getValue();
		if (newConvertedValue != convertedValue) {
     
			convertedValue = newConvertedValue;
			// Reset PropertyEditor: It already did a proper conversion.
			// Don't use it again for a setAsText call.
			editor = null;
		}
	}
	catch (Exception ex) {
     
		if (logger.isDebugEnabled()) {
     
			logger.debug("PropertyEditor [" + editor.getClass().getName() + "] does not support setValue call", ex);
		}
		// Swallow and proceed.
	}
}

1).先通过editor.setValue将实例化对象通过ValueOperationsEditor的setValue方法保存替换掉。ValueOperationsEditor类中的setValue方法已被重写,实例化对象通过符合条件的RedisOperations实例的opsForValue方法保存为ValueOperations类型了。而实现了RedisOperations接口的opsForValue方法只有RedisTemplate类。

public void setValue(Object value) {
     
	if (value instanceof RedisOperations) {
     
		super.setValue(((RedisOperations) value).opsForValue());
	} else {
     
		throw new IllegalArgumentException("Editor supports only conversion of type " + RedisOperations.class);
	}
}

2).通过editor.getValue()再获取该值。则可以注入。

参考点击这里.

入行不久,个人理解,方便记录

你可能感兴趣的:(java,redis)