一.错误信息如下:
***************************
APPLICATION FAILED TO START
***************************
Description:
Field redisTemplate in com.jr.service.planokr.utils.RedisUtil required a bean of type 'org.springframework.data.redis.core.RedisTemplate' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'org.springframework.data.redis.core.RedisTemplate' in your configuration.
Disconnected from the target VM, address: '127.0.0.1:51021', transport: 'socket'
Process finished with exit code 1
我的RedisTemplate注入如下:
@Autowired
RedisTemplate<String,Object> redisTemplate;
Redis配置类如下:
/**
* Redis配置类
*/
@Slf4j
@Configuration
@EnableCaching
public class RedisAutoConfiguration extends CachingConfigurerSupport {
// ================================================
// 以下是 Redis 序列化 的配置
// ================================================
@Bean(name="redisTemplate")
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
log.info("注入 redisTemplate");
RedisTemplate<String, String> template = new RedisTemplate<>();
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
template.setConnectionFactory(factory);
//key序列化方式
template.setKeySerializer(redisSerializer);
template.setHashKeySerializer(redisSerializer);
//value序列化
template.setValueSerializer(jackson2JsonRedisSerializer());
//value hashmap序列化
template.setHashValueSerializer(jackson2JsonRedisSerializer());
return template;
}
经过尝试,奇怪的是,不带泛型的RedisTemplate是可以正常注入的。
那么带泛型的类呢?
将 @Autowired 换成 @Resource 就可以啦!!!
@Resource
RedisTemplate<String,Object> redisTemplate;
由于我比较好奇,所以把RedisAutoConfiguration配置类中的@Bean(name="redisTemplate")直接改成@Bean,然后注入的时候用的 @Autowired,看看还报错吗?
呜呜呜呜,是我太天真了,还是一样的错,有点蒙不过没关系,找问题!!!
因为@Autowired是根据类型来注入的,泛型也被考虑进去了。
显然,我们的RedisTemplate里并没有我想要注入的这一类型,所以报错了;跟有没有name属性没啥关系。
想到这里,我才明白什么叫@Autowired注入是考虑泛型的。
而@Resource默认根据名称注入,redisTemplate 这个bean在我的RedisAutoConfiguration里被加到了spring中,所以是可以被注入的。并且redisTemplate方法名是唯一的。
如果非得想实现@Autowired注入的话,只要spring容器中有我们需要的类型的RedisTemple就可以啦,也就是说泛型必须一致咯才可以实现注入。
有的兄弟可能会有一个疑问?用@Autowired 配合@Qualifier 使用,不也是按名称注入的吗,但是忽略了一点是,虽然这样使用它会按名称找bean,但是它还是有bean 类型的限制的:
也就是说:bean中的泛型必须要和一想注入的保持一致。