Spring注解@Autowired和@Resource的区别详解
定义
@Autowired:默认byType进行自动装配,可以用于构造器、字段、方法注入,且必须有一个Bean候选者注入;如果允许出现0个Bean候选者需要设置属性"required=false","required"属性含义和@Required一样,只是@Required只适用于基于XML配置的setter注入方式。
@Resource:如果name和type属性都不指定,默认将先byName自动装配,找不到再byType;如果配置name属性,使用byName进行自动装配,而使用type时则使用byType进行装配;如果同时指定name和type,则从容器中找唯一匹配的bean装配,找不到抛出异常。
@Autowired 与@Resource区别
- @Autowired与@Resource都可以用来装配bean,都可以写在字段或setter方法上。
- @Resource是JDK提供的注解,默认按照名称进行装配,名称可通过name属性进行指定。如果没有指定name属性,当注解写在字段上时,默认取字段名,按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是如果name属性一旦指定,就只会按照名称进行装配。
- @Autowired默认按类型装配(Spring提供的注解),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false);如果想使用名称装配可以结合@Qualifier注解进行使用,如下:
@Autowired @Qualifier("baseDao") private BaseDao baseDao;
@Resource装配顺序:
①如果同时指定name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。
②如果指定name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。
③如果指定type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。
④如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。
@Resource的作用相当于@Autowired,只不过@Autowired按照byType自动注入。
@Resource 注解应该只用于setter方法注入和字段属性注入,不能提供如@Autowired多参数方法注入;
@Resource 首先将从JNDI环境中查找资源,如果没找到默认再到Spring容器中查找,因此如果JNDI环境中有和Spring容器同名的资源时需要注意。
autowired机制
Spring引入Autowire(自动装配)机制就是为了解决<bean>标签下<property>标签过多的问题: 如果一个Bean中要注入的对象过多,那将导致Spring配置文件非常冗长,可读性与维护性差,配置麻烦且一不小心就容易出错。
使用Autowire去除<property>标签
autowire有两处配置点:
可以配置在<beans>根标签下,表示对全局<bean>起作用,属性名为default-autowire
可以配置在<bean>标签下,表示对当前<bean>起作用,属性名为autowire
通常都是在<beans>根标签下配置自动装配比较多,default-autowire有四种取值:
- no:默认,即不进行自动装配,每一个对象的注入比如依赖一个<property>标签
- byName:按照beanName进行自动装配,使用setter注入
- byType:按照bean类型进行自动装配,使用setter注入
- constructor:不常用,与byType差不多,不过最终属性通过构造函数进行注入
byName意为在spring配置文件中查询beanName与属性名一致的bean并进行装配,若类型不匹配则报错;byType意为在spring配置文件中查询与属性类型一致的bean并进行装配,若有多个相同类型则报错。
byType装配出现多个相同类型的bean及解决方案 byType的装配方式是在Spring配置文件中寻找属性类型与bean类型一致的bean,如果属性类型在Spring配置文件中有多个相同类型的bean时,会报错:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name '*' defined in class path resource [*.xml]: Unsatisfied dependency expressed through bean property '*': : No unique bean of type [*.*.*] is defined: expected single matching bean but found 2: [*, *]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [*.*.*] is defined: expected single matching bean but found 2: [*, *]
解决方法:
- 将不需要进行自动装配的bean进行排除,设置其属性autowire-candidate="false";
- 当有多个候选者时,优先使用其中哪个候选者,对要作为自动装配候选者的bean设置primary="true";
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'apiController': Unsatisfied dependency expressed through field 'googleSqlService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'googleSqlService': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'adplanPutService' is expected to be of type 'com.aaa.cbd.platform.service.AdplanPutGoogleService' but was actually of type 'com.aaa.cbd.platform.service.AdplanPutService'
到此这篇关于Spring注解@Autowired和@Resource的区别详解的文章就介绍到这了,更多相关@Autowired和@Resource的区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Spring Boot Reactor 整合 Resilience4j详析
这篇文章主要介绍了Spring Boot Reactor整合Resilience4j详析,文章通过引入pom包展开详细介绍,具有一定的参考价值,感兴趣的小伙伴可以参考一下2022-09-09
最新评论