@Autowired, @Resource, @Inject 三個注解的區別你懂嗎?別再亂用了!


作者:Richard_Yi
來源:juejin.cn/post/6844904056230690824

本章的內容主要是想探討我們在進行Spring 開發過程當中,關於依賴注入的幾個問題。感興趣的讀者可以先看下以下三點:

  • @Autowired, @Resource, @Inject 三個注解的區別
  • 當你在使用@Autowired時,是否有出現過Field injection is not recommended的警告?你知道這是為什么嗎?
  • Spring 依賴注入有哪幾種方式?官方是怎么建議使用的呢?

如果你對上述問題都了解,那我個人覺得你的開發經驗應該是不錯的👍。如果你看到這三個問題很懵可以往下看。

下面我們就依次對上述問題進行解答,並且總結知識點。

@Autowired, @Resource, @Inject 三個注解的區別

Spring 支持使用@Autowired, @Resource, @Inject 三個注解進行依賴注入。下面來介紹一下這三個注解有什么區別。

推薦一個 Spring Boot 基礎教程及實戰示例:
https://github.com/javastacks/javastack

@Autowired

@Autowired為Spring 框架提供的注解,需要導入包org.springframework.beans.factory.annotation.Autowired

這里先給出一個示例代碼,方便講解說明:

public interface Svc {

    void sayHello();
}

@Service
public class SvcA implements Svc {

    @Override
    public void sayHello() {
        System.out.println("hello, this is service A");
    }

}

@Service
public class SvcB implements Svc {

    @Override
    public void sayHello() {
        System.out.println("hello, this is service B");
    }

}

@Service
public class SvcC implements Svc {

    @Override
    public void sayHello() {
        System.out.println("hello, this is service C");
    }
}

測試類:

@SpringBootTest
public class SimpleTest {

    @Autowired
    // @Qualifier("svcA")
    Svc svc;

    @Test
    void rc() {
        Assertions.assertNotNull(svc);
        svc.sayHello();
    }

}

裝配順序:

1.按照type在上下文中查找匹配的bean,查找type為Svc的bean

2.如果有多個bean,則按照name進行匹配

  • 如果有@Qualifier注解,則按照@Qualifier指定的name進行匹配,查找name為svcA的bean
  • 如果沒有,則按照變量名進行匹配,查找name為svcA的bean

3.匹配不到,則報錯。(@Autowired(required=false),如果設置requiredfalse(默認為true),則注入失敗時不會拋出異常)

@Inject

在Spring 的環境下,@Inject@Autowired 是相同的,因為它們的依賴注入都是使用AutowiredAnnotationBeanPostProcessor來處理的。

@Inject是 JSR-330 定義的規范,如果使用這種方式,切換到Guice也是可以的。

Guice 是 google 開源的輕量級 DI 框架

如果硬要說兩個的區別,首先@Inject是Java EE包里的,在SE環境需要單獨引入。另一個區別在於@Autowired可以設置required=false@Inject並沒有這個屬性。

@Resource

@Resource是JSR-250定義的注解。Spring 在 CommonAnnotationBeanPostProcessor實現了對JSR-250的注解的處理,其中就包括@Resource

@Resource有兩個重要的屬性:nametype,而Spring 將@Resource注解的name屬性解析為bean的名字,而type屬性則解析為bean的類型。

裝配順序:

  1. 如果同時指定了nametype,則從Spring上下文中找到唯一匹配的bean進行裝配,找不到則拋出異常。
  2. 如果指定了name,則從上下文中查找名稱(id)匹配的bean進行裝配,找不到則拋出異常。
  3. 如果指定了type,則從上下文中找到類型匹配的唯一bean進行裝配,找不到或是找到多個,都會拋出異常。
  4. 如果既沒有指定name,又沒有指定type,則默認按照byName方式進行裝配;如果沒有匹配,按照byTypeh進行裝配。

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2021最新版)

2.別在再滿屏的 if/ else 了,試試策略模式,真香!!

3.卧槽!Java 中的 xx ≠ null 是什么新語法?

4.Spring Boot 2.5 重磅發布,黑暗模式太炸了!

5.《Java開發手冊(嵩山版)》最新發布,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM