有非常多的小伙伴从大厂毕业,导致招聘也卷得相当厉害,不管是应届生、中开、高开,都会问技术原理。还经常问一些日常开发不太需要了解的知识点对比。今天,就给大家分享一个应届生被问到的一道面试题,在Spring中,@Autowired注解和@Resource注解的区别。
另外,我花了1个多星期把往期的面试题解析配套文档准备好了,想获取的小伙伴可以在我的煮叶简介中找到。
好了,先来看@Autowired 这个注解。
1、@Autowired注解
@Autowired这个注解呢,是由Spring提供的,它可以用来对构造方法、成员变量以及方法参数上进行标注,能够根据对象类型完成自动注入。
比如,这样
public class Service { //构造方法注入 @Autowired public Service(Service service) { this.service = service; } //成员变量注入 @Autowired private Service service; //方法参数注入 @Autowired public void setService(Service service) { this.service = service; } }
2、@Resource注解
再来看@Resource这个注解,
它是由JDK提供的,遵循JSR-250规范,是JDK1.6及以上加入的新特性。作为Java的标准,它的作用和@Autowired无区别。与@Autowired不同的是它可以适用于所有的Java框架,而@Autowired只适用于Spring。简单的理解@Resource能够支持对象类型注入,也能够支持对象名称注入。
3、@Resource和@Autowired的区别
那@Resource和@Autowired之间具体有哪些区别呢?我从以下五个方面来分析
1)、注解内部定义的参数不同
@Autowired只包含一个required参数,默认为true,表示开启自动注入。
public @interface Autowired { // 是否开启自动注入,不开启自动装配,可设为false。 boolean required() default true; }
而@Resource 包含七个参数,其中最重要的两个是name和type。
public @interface Resource { // bean的名称 String name() default ""; String lookup() default ""; // Java类,被解析为bean的类型 Class<?> type() default java.lang.Object.class; enum AuthenticationType { CONTAINER, APPLICATION } //身份验证类型 AuthenticationType authenticationType() default AuthenticationType.CONTAINER; //组件是否可以与其他组件之间共享 boolean shareable() default true; String mappedName() default ""; //描述 String description() default ""; }
2)、装配方式的默认值不同
@Autowired默认按type自动装配,而@Resource默认按name自动装配。当然,@Resource注解可以自定义选择,如果指定了name,则根据name自动装配,如果指定了type,则用type自动装配。
3)、注解应用的范围不同
@Autowired能够用在构造方法、成员变量、方法参数以及注解上,而@Resource能用在类、成员变量和方法参数上,这点从源码也能看得出来。
@Autowired能够用在构造方法、成员变量、方法参数以及注解上,而@Resource能用在类、成员变量和方法参数上,这点从源码也能看得出来。@Target({TYPE, FIELD, METHOD}) @Retention(RUNTIME) public @interface Resource { ... } @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Autowired { ... }
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Autowired { ... }
4)、出处不同
@Autowired是Spring定义的注解,而@Resource是遵循JSR-250规范,定义在JDK中。所以@Autowired只能在Spring框架下使用,而@Resource则可以与其他框架一起使用。
5)、装在顺序不同
@Autowired默认先按byType进行匹配,如果发现找到多个bean,则又按照byName方式进行匹配,如果还有多个,则报出异常。
而@Resource的装载顺序分为四种情况:
1)如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常,具体流程如图所示:
2)如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常,具体流程如图所示:
3) 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常,具体流程如图所示:
4)如果既没有指定name,也没有指定type,则自动按byName方式进行装配。如果没有匹配,则回退为按照类型进行匹配。
为了帮助大家更好地理解和区分,我还专门花时间整理一张表格。有需要的小伙伴可以关注我的主页介绍。
以上呢就是我对@Autowired与@Resource的总结和理解。总结一下,两者在功能上差别不大,使用起来也差不多。但是,在日常开发中,我建议使用@Autowired,有以下三个理由:
第1:@Autowired功能略强大。支持优先注入、可以配置允许bean不存在。
第2:若使用了Spring框架,使用其特有的注解个人感觉更好一点。
第3:有人会认为@Resource更加通用,因为它是个规范,其他框架也会支持。但我认为,目前后端都是在用Spring了,没有必要考虑其他框架。
当然,这个跟我个人是Spring迷无关哈,如果你也是Spring的小迷粉,可以关注我,一起交流,共同进步。