1.问题描述
一次我在维护一个springboot项目时,需要使用reids,当我注入redis 对象后 项目启动时报错日志如下:
@Resource
private StringRedisTemplate redisTemplate;
bean named 'redisTemplate' is expected to be of type
'org.springframework.data.redis.core.StringRedisTemplate'
but was actually of type 'org.springframework.data.redis.core.RedisTemplate'
2.问题分析
从日志报错我们可以知道,是注入对象报错, StringRedisTemplate
对象时使用了 @Resource
注解,但 @Resource
默认按名称注入对象,因此项目会寻找名为RedisTemplate
的对象。结果却需要 StringRedisTemplate
类型的对象,导致报错。改用 @Autowired
注解后,问题解决,因为它按类型注入对象
我在springboot项目中习惯使用 @Resource 注解来注入对象,因为使用 @Autowired 注解来注入对象时在编译器中有编译优化提示,看起来很闹心。
为什么会有编译优化提示呢?因为spirng是不推荐使用 @Autowired来注入对象的,推荐使用的是构造器注入。spring给出的官方回答如下:
过构造方法注入的方式,能够保证注入的组件不可变,并且能够确保需要的依赖不为空。此外,构造方法注入的依赖总是能够在返回客户端(组件)代码的时候保证完全初始化的状态。
1.依赖不可变:这个好理解,通过构造方法注入依赖,在对象创建的时候就要注入依赖,一旦对象创建成功,以后就只能使用注入的依赖而无法修改了,这就是依赖不可变(通过 set 方法注入将来还能通过 set 方法修改)。
2.依赖不为空:通过构造方法注入的时候,会自动检查注入的对象是否为空,如果为空,则注入失败;如果不为空,才会注入成功。
3.完全初始化:由于获取到了依赖对象(这个依赖对象是初始化之后的),并且调用了要初始化组件的构造方法,因此最终拿到的就是完全初始化的对象了。
我在项目基本不会使用构造器注入,因为当该类需要注入的对象很多时,构造器注入会让代码显的很臃肿,构造器注入方式如下:
3.注解比较
@Autowired 来源:@Autowired是Spring Framework的注解。 功能:用于自动装配Bean,可以按类型注入。 默认行为:默认情况下,它是按照类型进行自动装配。 依赖注入方式: 按类型:默认按类型匹配。 按名称:结合@Qualifier注解可以按名称进行装配。 可选性:通过required属性,可以指定是否必须注入(默认为true)。
@Resource 来源:@Resource是Java标准中的注解(JSR-250),在Spring中也可以使用。 功能:用于依赖注入,可以按名称或按类型注入。 默认行为:默认情况下,它是按照名称进行自动装配。 依赖注入方式: 按名称:默认按名称匹配。 按类型:如果名称匹配失败,会尝试按类型匹配。 可选性:没有required属性,无法指定是否必须注入。热点依然太原