从StringRedisTemplate注入问题深入探究@Resource和@Autowired两种注入方式的区别
StringRedisTemplate注入问题
1 | `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'` |
翻译:Spring框架期望一个名为 ‘redisTemplate’ 的bean 应该是类型为 ‘org.springframework.data.redis.core.StringRedisTemplate’,但实际上它是类型为 ‘org.springframework.data.redis.core.RedisTemplate’。
解决方式
方案一:改变注入方式
将@Resource
改为@Autowired
方案二:改命名
将redisTemplate/template
改为stringRedisTemplate
深入探究
两种注解区别
来源不同
@Autowired
是Spring提供的注解,它可以用来自动装配Spring容器中的bean,通常通过类型匹配来注入依赖。@Autowired
跟Spring框架强耦合了, 如果换成其他框架,@Autowired
就没作用了。@Resource
是Java EE 提供的注解,它也可以用来注入依赖,但更加通用,不仅可以注入Spring容器中的bean,还可以注入其他Java EE容器中的资源,通常通过名称匹配来注入依赖。@Resource
是JSR-250提供的,它是Java标准,绝大部分框架都支持。
内部参数定义不同
@Resource注解源码
1 | public Resource { |
@Autowired注解源码
1 | public Autowired { |
required()
:指示被注解的依赖是否是必需的。默认值为 true
,表示依赖是必需的,如果找不到匹配的bean,则会抛出异常。如果将其设置为 false
,则表示依赖是可选的,如果找不到匹配的bean,Spring容器将不会抛出异常,而是将该属性设置为 null
。
例如,如果 @Autowired(required = false)
,并且找不到匹配的bean,则不会抛出异常,而是将依赖设置为 null
。
注解应用范围不同
@Autowired能够用在构造方法、成员变量、方法参数以及注解上
1 |
@Resource能用在类、成员变量和方法参数上
1 |
装配方式不同
@Autowired默认按type自动装配,而@Resource默认按name自动装配。当然,@Resource注解可以自定义选择,如果指定了name,则根据name自动装配,如果指定了type,则用type自动装配。
装配顺序不同
@Autowired
装配顺序:
@Autowired默认先与byType进行匹配,如果发现找到多个Bean,则又按照byName方式进行匹配,如果还有多个Bean,则报出异常。装配顺序如下图所示。
@Resource
装配顺序:
1)如果同时指定name和type,则从Spring上下文中找到与它们唯一匹配的Bean进行装配,如果找不到则抛出异常,具体流程如下图所示。
2)如果指定name,则从上下文中查找与名称(ID)匹配的Bean进行装配,如果找不到则抛出异常,具体流程如下图所示。
3)如果指定type,则从上下文中找到与类型匹配的唯一Bean进行装配,如果找不到或者找到多个就会抛出异常,具体流程如下图所示。
4)如果既没有指定name,也没有指定type,则自动按byName方式进行装配。如果没有匹配成功,则仍按照type进行匹配,具体流程如下图所示。