@Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入。
1、共同点
两者都可以写在字段和setter方法上。两者如果都写在字段上,那么就不需要再写setter方法。
@Autowired是spring的注解,Autowire为ByType的方式注入,被注入的成员的名称可以任意取名,当容器中的bean存在多个的情况下,@Autowire为ByName的方式注入
@Resource默认按照ByName自动注入,@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。
@Autowired注解
方法注入和属性注入,两者注入的原理是一样的,都是先跟距type查找匹配的bean,若查找结果为多个,那么接下来跟距name去查找匹配相关bean
如下代码,我们回向spring 容器中注入三个bean
如果我们使用一个不存在的name,那么spring就会抛出异常
其实@Autowired注解进行依赖注入时,在spring底层,会经过以下多个判断过程。
autowireCandidate是否为true
如下我们将其中两个bean的 autowireCandidate属性设置成false
那么在通过byType的到的三个bean经过autowireCandidate的判断 bean orderService1和orderService2也被过滤掉了,所以此时在注入时就不会进行name判断了(只剩一个符合条件的bean)
即name 为orderService的bean符合匹配规则
我们对注入的名字随意命名,都可以正常运行:
我们可以修改其中一个autowireCandidate为true,不存在的bean name orderService5就会报错
并且注入orderService1,也会报错:
但是orderService或者orderService2就不会报错:
接下来判断是不是符合Qualifier
如果bean的设置和引用的都有相同的Qualifier name,那么也会直接注入不用判断bean name是否匹配
取@Primary标注的bean
@Priority()注解
@Priority(),用于注解类,参数是int l类型,spring容器会优先加载@Priority(),值小的bean
byname
在经过以上判断后,如果仍然没有挑选出匹配的bean ,最后,谈过bean name 进行最后匹配。
@Resource注入
如果@Resource注解指定了name属性
就直接从spring容器拿对应的bean,如果不存在就表示没有找到注入对象。
orderService1存在
orderService5不存在
如果@Resource注解没有指定name属性
根据属性的名字,去spring容器查找对应的bean
如果有,直接取出。
如果没有,根据注入点type找bean
如果我们符合的只有一个,那么是可以正常运行的
运行结果正常