五个维度,解析 Spring 中 @Autowired 和 @Resource 的区别

@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;
 
    }
}

再来看@Resource注解,代码如下:

public class Service {
    
    @Resource(name = "service1")
    private Service service1;
    
    @Resource(name = "service2")
    private Service service2;
 

    @Reource
    private Service service3;
 
    @Reource
    private Service service4;

}

它是由JDK提供的,遵循JSR-250规范,是JDK 1.6及以上加入的新特性。作为Java的标准,它的作用和@Autowired无区别。与@Autowired不同的是,它适用于所有的Java框架,而@Autowired只适用于Spring。读者可以简单地理解为,@Resource能够支持对象类型注入,也能够支持对象名称注入。

@Resource和@Autowired之间具体有哪些区别呢?

可以从以下5个方面来分析。

1.注解内部定义的参数不同

@Autowired只包含一个required参数,默认为true,表示开启自动注入。

public @interface Autowired {

     // 是否开启自动注入,在不开启自动装配时,可设为false

    boolean required() default true;
 
}

@Resource 包含7个参数,其中最重要的两个是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能用在类、成员变量和方法参数上,源码如下。

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired { ... }

@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {  ... }

4.出处不同

@Autowired是Spring定义的注解,而@Resource遵循JSR-250的规范,定义在JDK中。所以@Autowired只能在Spring框架下使用,而@Resource则可以与其他框架一起使用。

5.装配顺序不同

@Autowired默认先与byType进行匹配,如果发现找到多个Bean,则又按照byName方式进行匹配,如果还有多个Bean,则报出异常。装配顺序如下图所示。

五个维度,解析 Spring 中 @Autowired 和 @Resource 的区别

而@Resource的装载顺序分为如下4种情况。

1)如果同时指定name和type,则从Spring上下文中找到与它们唯一匹配的Bean进行装配,如果找不到则抛出异常,具体流程如下图所示。

五个维度,解析 Spring 中 @Autowired 和 @Resource 的区别

2)如果指定name,则从上下文中查找与名称(ID)匹配的Bean进行装配,如果找不到则抛出异常,具体流程如下图所示。

五个维度,解析 Spring 中 @Autowired 和 @Resource 的区别

3)如果指定type,则从上下文中找到与类型匹配的唯一Bean进行装配,如果找不到或者找到多个就会抛出异常,具体流程如下图所示。

五个维度,解析 Spring 中 @Autowired 和 @Resource 的区别

4)如果既没有指定name,也没有指定type,则自动按byName方式进行装配。如果没有匹配成功,则仍按照type进行匹配,具体流程如下图所示。

五个维度,解析 Spring 中 @Autowired 和 @Resource 的区别

下面这张表可以帮助大家更好地理解和区分@Autowired和@Resource。

五个维度,解析 Spring 中 @Autowired 和 @Resource 的区别

总结一下,两者在功能上差别不大,使用起来也差不多。但是,在日常开发中建议使用@Autowired,有以下3个理由。

  • @Autowired功能略强大。支持优先注入、可以配置允许Bean不存在。

  • 若使用Spring框架,则使用其特有的注解更好一点。

  • 有人认为@Resource更加通用,因为它是一个规范,其他框架也会支持。目前后端都在用Spring,没有必要考虑其他框架。

面试点评:我们可以直接告诉面试官这两个注解的差异,同时基于两个注解的特性解释更多的差异,这样可以更好地体现自己对这方面知识的理解深度。面试官想考查求职者对Spring依赖注入方式的理解,以及对@Autowired和@Resource两个注解底层实现方面的区别的理解。求职者在理解了底层实现的差异后,回答这个问题会比较容易。


Java基础知识,多线程,并发编程,集合原理,JVM原理……啊!别跟我提这些!面试官一下子拿着这些知识点就冲你扔过来,还有那魔幻的Java框架,你要是不懂Spring全家桶、Dubbo、Netty、Mybatis等,就别想踏进这个行业的大门。没错,Java领域可是卷得一塌糊涂啊。

现在有了一本强大的新书空降,在这炽热的夏日带来一股清凉的Java知识。这本名叫《Java面试八股文:高频面试题与求职攻略一本通》,简直是Java求职者的救星。

本文也是摘录这本书的一个片段,有需要了解的,可以看看:

原文始发于微信公众号(Java知音):五个维度,解析 Spring 中 @Autowired 和 @Resource 的区别

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/147682.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!