Java面试题:让依赖注入变得简单,面对@Autowired和@Resource,该如何选择?

@Autowired和@Resource都是Java Spring框架中的注解,用于实现依赖注入(DI)和控制反转(IoC)。

它们的区别主要在以下三个方面:

源头不同

@Autowired是Spring自带的注解,而@Resource是JSR 250规范中定义的注解。因此,在使用Spring框架的时候,通常建议使用@Autowired注解。

查找顺序不同

在注入Bean时,@Autowired注解的查找顺序为:先按类型(byType)匹配,如果有多个Bean符合该类型,则再按照名称(byName)进行匹配。如果两种方式都无法唯一确定Bean,则会抛出异常。

伪代码如下:

复制代码
public class Person {
    private Phone phone;

    @Autowired
    public void setPhone(Phone phone) {
        this.phone = phone;
    }

    //...
}

public interface Phone {
    //...
}

@Component("apple")
public class ApplePhone implements Phone {
    //...
}

@Component("huawei")
public class HuaweiPhone implements Phone {
    //...
}

在上面的示例中,如果有ApplePhone和HuaweiPhone两个Bean都实现了Phone接口,那么当Person类的setPhone方法被调用时,Spring会根据类型匹配到这两个Bean,但是无法唯一确定,此时会抛出异常。可以通过添加@Qualifier注解来指定具体的Bean:
伪代码如下:

复制代码
@Autowired
@Qualifier("apple")
public void setPhone(Phone phone) {
    this.phone = phone;
}

而@Resource注解的查找顺序为:先按照名称(byName)进行匹配,如果无法匹配到Bean,则再按照类型(byType)进行匹配。
伪代码如下:

复制代码
public class Person {
    private Phone phone;

    @Resource(name = "apple")
    public void setPhone(Phone phone) {
        this.phone = phone;
    }

    //...
}

@Component("apple")
public class ApplePhone implements Phone {...}

@Component("huawei")
public class HuaweiPhone implements Phone {...}

在上面的示例中,当Person类的setPhone方法被调用时,Spring会先根据名称查找是否有名称为"apple"的Bean,如果有,则直接注入;如果没有,则再根据类型匹配。

适用范围不同

@Autowired注解可以用于构造器、Setter方法、字段和方法上,而@Resource注解只能用于字段和方法上。因此,如果需要在构造器中注入Bean,就必须使用@Autowired注解。综上所述,建议在使用Spring框架时,尽量使用@Autowired注解。

以下是具体的代码示例:

复制代码
public interface Phone {
    String brand();
}

@Component("apple")
public class ApplePhone implements Phone {
    @Override
    public String brand() {
        return "Apple";
    }
}

@Component("huawei")
public class HuaweiPhone implements Phone {
    @Override
    public String brand() {
        return "Huawei";
    }
}

@Component
public class Person {

    // 使用@Autowired注解进行注入
    @Autowired
    private Phone phone1;

    // 使用@Resource注解进行注入,指定名称
    @Resource(name = "apple")
    private Phone phone2;

    private Phone phone3;

    public void setPhone3(Phone phone3) {
        this.phone3 = phone3;
    }

    // 使用@Autowired注解和@Qualifier注解进行注入
    @Autowired
    @Qualifier("huawei")
    public void setPhone4(Phone phone4) {
        this.phone4 = phone4;
    }
}

在上面的示例中,Person类中有四个属性需要注入Bean。其中,phone1属性使用了@Autowired注解,使用默认的查找方式进行注入;phone2属性使用了@Resource注解,并指定了名称为"apple"的Bean进行注入;phone3属性没有。

总结一下:

  • @Autowired是Spring框架提供的注解,@Resource是Java EE 5规范提供的注解。

  • @Autowired默认按照类型自动装配,而@Resource默认按照名称自动装配。

  • @Autowired支持@Qualifier注解来指定装配哪一个具有相同类型的bean,而@Resource 默认按照名称进行注入,如果指定了name或者type属性,则会按照指定的名称或者类型来查找对应的Bean实例进行注入

综上所述,@Autowired更加灵活,但也更加复杂;@Resource更加简单、直观,适用于简单的场景。

往期面试题:

Java面试题:如果你这样做,你会后悔的,两次启动同一个线程~~~

Java面试题:@PostConstruct、init-method和afterPropertiesSet执行顺序?

Java面试题:SimpleDateFormat是线程安全的吗?使用时应该注意什么?

Java面试题:细数ThreadLocal大坑,内存泄露本可避免

Java面试题:请谈谈对ThreadLocal的理解?

Java面试题:为什么HashMap不建议使用对象作为Key?

Java面试题:你知道Spring的IOC吗?那么,它为什么这么重要呢?

Java面试题:线程池内"闹情绪"的线程,怎么办?

Java面试题:Spring Bean线程安全?别担心,只要你不写并发代码就好了!

Java面试题:Spring框架除了IOC和AOP,还有哪些好玩的设计模式?

相关推荐
C雨后彩虹2 小时前
竖直四子棋
java·数据结构·算法·华为·面试
疾风sxp2 小时前
nl2sql技术实现自动sql生成之langchain4j SqlDatabaseContentRetriever
java·人工智能·langchain4j
一勺菠萝丶3 小时前
PDF24 转图片出现“中间横线”的根本原因与终极解决方案(DPI 原理详解)
java
姓蔡小朋友3 小时前
Unsafe类
java
一只专注api接口开发的技术猿3 小时前
如何处理淘宝 API 的请求限流与数据缓存策略
java·大数据·开发语言·数据库·spring
荒诞硬汉3 小时前
对象数组.
java·数据结构
期待のcode3 小时前
Java虚拟机的非堆内存
java·开发语言·jvm
黎雁·泠崖3 小时前
Java入门篇之吃透基础语法(二):变量全解析(进制+数据类型+键盘录入)
java·开发语言·intellij-idea·intellij idea
仙俊红3 小时前
LeetCode484周赛T4
java