0%

Spring源码 Autowired与Resource

最近项目中发现对Spring中的Autowired和JSR-250 定义的Resource认知还是比较模糊,网上的大多的解释也比较笼统,没能解释清楚我的疑问,于是自己动手,丰衣足食,总结如下。

先来一段官方的解释,其实官方的解释意境很清楚了。
If you intend to express annotation-driven injection by name, do not primarily use @Autowired, even if is technically capable of referring to a bean name through @Qualifier values. Instead, use the JSR-250 @Resource annotation, which is semantically defined to identify a specific target component by its unique name, with the declared type being irrelevant for the matching process.
As a specific consequence of this semantic difference, beans that are themselves defined as a collection or map type cannot be injected through @Autowired, because type matching is not properly applicable to them. Use @Resource for such beans, referring to the specific collection or map bean by unique name.
@Autowired applies to fields, constructors, and multi-argument methods, allowing for narrowing through qualifier annotations at the parameter level. By contrast, @Resource is supported only for fields and bean property setter methods with a single argument. As a consequence, stick with qualifiers if your injection target is a constructor or a multi-argument method.

除了注解使用的地方不同外,比如:Autowired可以用在多参数的方法上等而Resource就只能用在变量、set方法上等,这个不再赘述。

主要关注其实现的解释。

Autowired网上大多解释是按照类型进行装配,给人一种只会按照类型匹配的误解,其实不然,当Autowired遇到候选类型有多个实例但实际需要注入的不是集合类型(List)或者Map的时候,默认会按照变量名称对候选类型进行筛选,此时如果没找到就会抛出异常。下图是Autowired确定候选的代码。

这里写图片描述

Resource网上大多也简单解释为按照名称装配,当Resource没有在单例池中找到指定名称的bean,就会在bean定义池中找bean定义,然后去创建这个bean实例(即:调用beanFactory的doGetBean方法)。当然,不管其过程怎样,在返回bean实例前还是要对bean的类型进行检查,如果不是想要的类型,还是会抛出异常。代码片段如下,可以看到,在从beanFactory中拿bean实例的时候还是传入了类型,供确定bean实例用。

这里写图片描述

在返回bean实例前,对bean类型进行检查。

这里写图片描述

小生不才,以上如有描述有误的地方还望各位不吝赐教 !^_^!