亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

搜索
首頁 > Java > java教程 > 正文

@Autowired 和 @Resource 注解的區(qū)別是什么?

紅蓮之龍
發(fā)布: 2025-09-03 22:02:01
原創(chuàng)
500人瀏覽過
@Autowired按類型注入,需@Qualifier或@Primary解決多實(shí)例歧義;@Resource優(yōu)先按名稱注入,名稱不匹配時按類型,更利于名稱明確的場景。

@autowired 和 @resource 注解的區(qū)別是什么?

@Autowired 側(cè)重于按類型進(jìn)行依賴注入,是 Spring 框架特有的;而 @Resource 則優(yōu)先按名稱進(jìn)行注入,是 Java EE 規(guī)范的一部分,可以脫離 Spring 獨(dú)立使用。

解決方案

理解

@Autowired
登錄后復(fù)制
@Resource
登錄后復(fù)制
區(qū)別,說到底就是理解它們在查找和匹配依賴時的策略差異。

@Autowired:Spring 的類型優(yōu)先策略

@Autowired
登錄后復(fù)制
是 Spring 框架提供的注解,它的核心思想是“按類型裝配”(by type)。當(dāng)你在一個字段、構(gòu)造器或 Setter 方法上使用
@Autowired
登錄后復(fù)制
時,Spring 容器會嘗試在它管理的 Bean 中找到一個類型匹配的 Bean 來進(jìn)行注入。

例如:

@Component
public class MyService {
    @Autowired
    private MyRepository myRepository; // Spring會尋找MyRepository類型的Bean
    // ...
}
登錄后復(fù)制

這里,Spring 會在容器中查找

MyRepository
登錄后復(fù)制
接口或類的實(shí)現(xiàn)。如果容器中只有一個
MyRepository
登錄后復(fù)制
類型的 Bean,那么它就會被成功注入。但如果容器中有多個
MyRepository
登錄后復(fù)制
類型的 Bean(比如
MyRepositoryImplA
登錄后復(fù)制
MyRepositoryImplB
登錄后復(fù)制
都實(shí)現(xiàn)了
MyRepository
登錄后復(fù)制
接口),Spring 就會感到困惑,拋出
NoUniqueBeanDefinitionException
登錄后復(fù)制
異常,因?yàn)樗恢涝撟⑷肽囊粋€。

為了解決這種歧義,你可以配合

@Qualifier
登錄后復(fù)制
注解,明確指定要注入的 Bean 的名稱:

@Component
public class MyService {
    @Autowired
    @Qualifier("myRepositoryImplA") // 明確指定Bean的名稱
    private MyRepository myRepository;
    // ...
}
登錄后復(fù)制

或者,你也可以將其中一個實(shí)現(xiàn)類標(biāo)記為

@Primary
登錄后復(fù)制
,告訴 Spring 在有多個相同類型的 Bean 時,優(yōu)先選擇這個:

@Component
@Primary
public class MyRepositoryImplA implements MyRepository { /* ... */ }

@Component
public class MyRepositoryImplB implements MyRepository { /* ... */ }

// MyService中無需@Qualifier,Spring會默認(rèn)注入MyRepositoryImplA
@Component
public class MyService {
    @Autowired
    private MyRepository myRepository;
    // ...
}
登錄后復(fù)制

@Resource:Java EE 的名稱優(yōu)先策略

@Resource
登錄后復(fù)制
注解是 JSR-250 規(guī)范的一部分,這意味著它不局限于 Spring 框架,也可以在其他 Java EE 容器(如 Tomcat、Glassfish)中使用。它的默認(rèn)行為是“按名稱裝配”(by name)。

當(dāng)你在一個字段或 Setter 方法上使用

@Resource
登錄后復(fù)制
時,它的查找順序是這樣的:

  1. 按名稱查找: 默認(rèn)情況下,
    @Resource
    登錄后復(fù)制
    會嘗試將注解所在字段的名稱(或者 Setter 方法對應(yīng)的屬性名)作為 Bean 的名稱去容器中查找。
    @Component
    public class MyService {
        @Resource
        private MyRepository myRepositoryImplA; // 會嘗試查找名為"myRepositoryImplA"的Bean
        // ...
    }
    登錄后復(fù)制

    如果找到了,就注入。

  2. 按類型查找: 如果按名稱沒有找到匹配的 Bean,
    @Resource
    登錄后復(fù)制
    就會退而求其次,嘗試按類型進(jìn)行查找。如果找到一個類型匹配的 Bean,就注入。如果找到多個類型匹配的 Bean,它會拋出異常。

你也可以通過

@Resource
登錄后復(fù)制
name
登錄后復(fù)制
屬性明確指定要注入的 Bean 的名稱:

@Component
public class MyService {
    @Resource(name = "myRepositoryImplA") // 明確指定Bean的名稱
    private MyRepository myRepository;
    // ...
}
登錄后復(fù)制

或者通過

type
登錄后復(fù)制
屬性指定類型,但這通常不如
name
登錄后復(fù)制
屬性常用,因?yàn)槊Q匹配是其核心優(yōu)勢:

@Component
public class MyService {
    @Resource(type = MyRepository.class) // 按類型查找
    private MyRepository someRepository;
    // ...
}
登錄后復(fù)制

總結(jié)來說,核心差異是:

@Autowired
登錄后復(fù)制
默認(rèn)是類型優(yōu)先,需要
Qualifier
登錄后復(fù)制
輔助名稱;
@Resource
登錄后復(fù)制
默認(rèn)是名稱優(yōu)先,找不到名稱再退化到類型。

Spring Boot開發(fā)中,何時優(yōu)先選擇@Autowired,何時選擇@Resource?

在 Spring Boot 的日常開發(fā)中,選擇

@Autowired
登錄后復(fù)制
還是
@Resource
登錄后復(fù)制
,這其實(shí)更多是一種個人習(xí)慣和團(tuán)隊(duì)規(guī)范的體現(xiàn),當(dāng)然,也有些場景會讓我傾向于某一個。

我個人在多數(shù)情況下會更傾向于使用

@Autowired
登錄后復(fù)制
。為什么呢?因?yàn)?Spring Boot 項(xiàng)目本身就是深度依賴 Spring 框架的,
@Autowired
登錄后復(fù)制
作為 Spring 原生的注解,用起來感覺更“順滑”,也更符合 Spring 的設(shè)計(jì)哲學(xué)——即通過類型來建立依賴關(guān)系。當(dāng)我在一個純粹的 Spring 環(huán)境中工作時,我希望我的代碼能夠充分利用 Spring 提供的便利,而
@Autowired
登錄后復(fù)制
恰好提供了這種簡潔和直觀的類型匹配能力。特別是當(dāng)我的接口只有一個實(shí)現(xiàn)類時,
@Autowired
登錄后復(fù)制
幾乎是零配置,非常方便。如果遇到多實(shí)現(xiàn)的情況,
@Qualifier
登錄后復(fù)制
的存在也提供了一個優(yōu)雅的解決方案。

然而,在某些特定的場景下,我會發(fā)現(xiàn)

@Resource
登錄后復(fù)制
更有用武之地。比如,當(dāng)我在處理一些遺留系統(tǒng),或者與一些第三方庫集成時,這些庫可能在 Spring 容器中注冊了一些名稱很明確的 Bean,但它們的類型可能比較通用,或者我只是想通過一個特定的名稱來引用它們。這時候,
@Resource
登錄后復(fù)制
的名稱優(yōu)先匹配策略就顯得非常直接和清晰,它能夠減少潛在的類型匹配混淆。

再比如,如果我需要在代碼中顯式地通過一個字符串名稱來引用一個 Bean(這在某些動態(tài)配置或工廠模式中可能會出現(xiàn)),那么

@Resource(name="beanName")
登錄后復(fù)制
的表達(dá)力就比
@Autowired
登錄后復(fù)制
結(jié)合
@Qualifier("beanName")
登錄后復(fù)制
顯得更直接一些,因?yàn)樗选鞍疵Q注入”這個意圖放在了注解本身。

另外,從代碼的可移植性角度看,

@Resource
登錄后復(fù)制
因?yàn)槭?Java EE 規(guī)范的一部分,理論上它的代碼可以更容易地遷移到其他支持 JSR-250 的 Java EE 容器中。盡管在 Spring Boot 項(xiàng)目中,這種可移植性優(yōu)勢往往被淡化了(因?yàn)槟阋呀?jīng)選擇了 Spring),但對于那些對規(guī)范性有較高要求,或者未來有潛在遷移需求的項(xiàng)目,
@Resource
登錄后復(fù)制
確實(shí)提供了一種更標(biāo)準(zhǔn)化的選擇。

魔樂社區(qū)
魔樂社區(qū)

天翼云和華為聯(lián)合打造的AI開發(fā)者社區(qū),支持AI模型評測訓(xùn)練、全流程開發(fā)應(yīng)用

魔樂社區(qū)102
查看詳情 魔樂社區(qū)

所以,我的經(jīng)驗(yàn)是:對于大多數(shù) Spring Boot 應(yīng)用的內(nèi)部組件依賴,

@Autowired
登錄后復(fù)制
是一個非常好的默認(rèn)選擇;而當(dāng)涉及到與外部系統(tǒng)集成、處理遺留代碼、或者需要通過明確名稱來消除歧義時,
@Resource
登錄后復(fù)制
會是更穩(wěn)健和清晰的選擇。

如果存在多個相同類型的Bean,這兩種注解會如何處理?

處理多個相同類型的 Bean,是我們在 Spring 開發(fā)中經(jīng)常會遇到的一個挑戰(zhàn),也是區(qū)分

@Autowired
登錄后復(fù)制
@Resource
登錄后復(fù)制
行為的關(guān)鍵點(diǎn)。

@Autowired 的處理方式:

當(dāng) Spring 容器中存在多個類型相同的 Bean,而你又使用了

@Autowired
登錄后復(fù)制
進(jìn)行注入時,如果沒有額外的指示,Spring 會感到“不知所措”,因?yàn)樗恢缿?yīng)該選擇哪一個 Bean。在這種情況下,它會拋出一個
NoUniqueBeanDefinitionException
登錄后復(fù)制
異常。這個異常會明確告訴你,容器中找到了多個符合類型的 Bean,需要你進(jìn)行進(jìn)一步的明確。

為了解決這個問題,通常有以下幾種方法:

  1. 使用

    @Qualifier
    登錄后復(fù)制
    這是最常用也最推薦的方式。通過在
    @Autowired
    登錄后復(fù)制
    的同時加上
    @Qualifier("beanName")
    登錄后復(fù)制
    ,你可以明確告訴 Spring 要注入哪個具體名稱的 Bean。

    @Service("smsSender")
    public class SmsSender implements MessageSender { /* ... */ }
    
    @Service("emailSender")
    public class EmailSender implements MessageSender { /* ... */ }
    
    @Component
    public class NotificationService {
        @Autowired
        @Qualifier("emailSender") // 明確指定注入名為 "emailSender" 的Bean
        private MessageSender messageSender;
    }
    登錄后復(fù)制
  2. 使用

    @Primary
    登錄后復(fù)制
    如果你希望在多個相同類型的 Bean 中,有一個是默認(rèn)優(yōu)先被注入的,你可以將該 Bean 標(biāo)記為
    @Primary
    登錄后復(fù)制
    。這樣,當(dāng) Spring 遇到類型沖突時,會優(yōu)先選擇帶有
    @Primary
    登錄后復(fù)制
    注解的 Bean。

    @Service
    @Primary // 優(yōu)先選擇這個發(fā)送器
    public class DefaultSmsSender implements MessageSender { /* ... */ }
    
    @Service
    public class BackupEmailSender implements MessageSender { /* ... */ }
    
    @Component
    public class NotificationService {
        @Autowired // 會自動注入 DefaultSmsSender
        private MessageSender messageSender;
    }
    登錄后復(fù)制
  3. 通過參數(shù)名匹配(作為后備): 如果沒有

    @Qualifier
    登錄后復(fù)制
    也沒有
    @Primary
    登錄后復(fù)制
    ,Spring 還會嘗試將要注入的字段名或參數(shù)名作為 Bean 的名稱進(jìn)行匹配。但這種方式不如前兩種明確,且容易引發(fā)混淆,我個人不太推薦在多 Bean 場景下依賴它。

@Resource 的處理方式:

@Resource
登錄后復(fù)制
在處理多個相同類型的 Bean 時,其行為邏輯有所不同,因?yàn)樗旧砭褪敲Q優(yōu)先的。

  1. 優(yōu)先按名稱查找: 當(dāng)你使用

    @Resource
    登錄后復(fù)制
    注解時,它會首先嘗試根據(jù)字段名(或 Setter 方法名)來查找 Bean。如果找到了一個名稱匹配的 Bean,即使有多個相同類型的 Bean,它也會直接注入這個名稱匹配的 Bean,不會引發(fā)歧義。

    @Service("smsSender")
    public class SmsSender implements MessageSender { /* ... */ }
    
    @Service("emailSender")
    public class EmailSender implements MessageSender { /* ... */ }
    
    @Component
    public class NotificationService {
        @Resource // 嘗試查找名為 "smsSender" 的Bean
        private MessageSender smsSender;
    
        @Resource // 嘗試查找名為 "emailSender" 的Bean
        private MessageSender emailSender;
    }
    登錄后復(fù)制
  2. 如果按名稱未找到,再按類型查找: 如果

    @Resource
    登錄后復(fù)制
    沒有通過名稱找到匹配的 Bean,它才會退而求其次,嘗試按類型進(jìn)行查找。在這種情況下,如果容器中存在多個相同類型的 Bean,并且它們都沒有被
    @Resource
    登錄后復(fù)制
    的名稱屬性明確指定,那么
    @Resource
    登錄后復(fù)制
    同樣會拋出異常,因?yàn)樗鼰o法決定注入哪一個。

所以,從處理多 Bean 的角度看,

@Resource
登錄后復(fù)制
在一開始就通過名稱匹配的策略,能夠在很多情況下避免歧義。而
@Autowired
登錄后復(fù)制
則需要你顯式地通過
@Qualifier
登錄后復(fù)制
@Primary
登錄后復(fù)制
來解決這種歧義。

從代碼可移植性和規(guī)范性角度,這兩種注解有何優(yōu)劣?

談到代碼的可移植性和規(guī)范性,

@Autowired
登錄后復(fù)制
@Resource
登錄后復(fù)制
確實(shí)展現(xiàn)出了不同的哲學(xué)和定位。

@Autowired:Spring 框架的深度整合與便捷性

  • 優(yōu)點(diǎn):
    • 與 Spring 深度整合:
      @Autowired
      登錄后復(fù)制
      是 Spring 框架的核心組成部分,它與 Spring 的 IoC 容器、AOP、事務(wù)管理等功能無縫集成。在純 Spring 或 Spring Boot 項(xiàng)目中,使用
      @Autowired
      登錄后復(fù)制
      感覺非常自然,也最能體現(xiàn) Spring 的“約定優(yōu)于配置”理念。
    • 簡潔性: 對于大多數(shù)只有單一實(shí)現(xiàn)類的接口,
      @Autowired
      登錄后復(fù)制
      幾乎是零配置,代碼非常簡潔。
    • 類型安全: 默認(rèn)的類型匹配策略在編譯時就能發(fā)現(xiàn)一些潛在的類型不匹配問題(當(dāng)然,運(yùn)行時找不到 Bean 還是會報(bào)錯)。
  • 缺點(diǎn):
    • 框架耦合度高: 這是最主要的“劣勢”。
      @Autowired
      登錄后復(fù)制
      是 Spring 特有的注解,如果你的代碼將來需要從 Spring 容器遷移到其他非 Spring 的 IoC 容器(比如一個純 Java EE 容器,或者一個自定義的輕量級容器),那么所有使用了
      @Autowired
      登錄后復(fù)制
      的地方都需要進(jìn)行修改。這會增加遷移成本。當(dāng)然,在實(shí)際的 Spring Boot 項(xiàng)目中,這種遷移的可能性通常很低,因?yàn)?Spring Boot 本身就意味著對 Spring 生態(tài)的深度依賴。
    • 默認(rèn)行為可能引發(fā)歧義: 如前所述,在存在多個相同類型的 Bean 時,
      @Autowired
      登錄后復(fù)制
      默認(rèn)會報(bào)錯,需要額外的
      @Qualifier
      登錄后復(fù)制
      @Primary
      登錄后復(fù)制
      來解決。

@Resource:Java EE 標(biāo)準(zhǔn)的通用性與規(guī)范性

  • 優(yōu)點(diǎn):
    • 高可移植性: 這是
      @Resource
      登錄后復(fù)制
      最顯著的優(yōu)勢。作為 JSR-250 規(guī)范的一部分,
      @Resource
      登錄后復(fù)制
      是 Java EE 容器的標(biāo)準(zhǔn)注解。這意味著使用了
      @Resource
      登錄后復(fù)制
      的代碼理論上可以在任何支持 JSR-250 的 Java EE 容器中工作,而不僅僅局限于 Spring。對于那些需要考慮跨平臺或未來可能遷移到不同容器的場景,
      @Resource
      登錄后復(fù)制
      提供了一層抽象,降低了框架鎖定的風(fēng)險(xiǎn)。
    • 規(guī)范性: 遵循 Java EE 規(guī)范,使得代碼在宏觀上更具“標(biāo)準(zhǔn)”感,這對于一些對架構(gòu)規(guī)范有嚴(yán)格要求的企業(yè)或項(xiàng)目來說可能是一個加分項(xiàng)。
    • 名稱優(yōu)先的清晰性: 其默認(rèn)的名稱匹配策略在很多情況下能夠更直觀地表達(dá)注入意圖,尤其是在 Bean 名稱具有明確業(yè)務(wù)含義時。
  • 缺點(diǎn):
    • 與 Spring 框架的集成不如
      @Autowired
      登錄后復(fù)制
      緊密:
      盡管 Spring 完全支持
      @Resource
      登錄后復(fù)制
      ,但它畢竟不是 Spring 原生的。在某些 Spring 特有的高級特性或擴(kuò)展點(diǎn)上,
      @Autowired
      登錄后復(fù)制
      可能表現(xiàn)得更自然。
    • 在 Spring Boot 環(huán)境下,可移植性優(yōu)勢可能被弱化: 就像我前面說的,一旦你選擇了 Spring Boot,你通常就已經(jīng)接受了對 Spring 框架的深度依賴。在這種情況下,
      @Resource
      登錄后復(fù)制
      的可移植性優(yōu)勢在實(shí)踐中可能并不那么突出。

我的看法:

在我的實(shí)際開發(fā)經(jīng)驗(yàn)中,如果項(xiàng)目是全新的 Spring Boot 應(yīng)用,且不預(yù)期有任何脫離 Spring 框架的可能,我通常會選擇

@Autowired
登錄后復(fù)制
。它更符合 Spring 的編程模型,也更簡潔。然而,如果我正在維護(hù)一個老項(xiàng)目,或者一個需要與多種技術(shù)棧集成的模塊,或者團(tuán)隊(duì)對 Java EE 規(guī)范有特別的偏好,那么
@Resource
登錄后復(fù)制
就會成為一個非常有吸引力的選擇。它提供了一種更標(biāo)準(zhǔn)化的依賴注入方式,讓代碼看起來更“規(guī)矩”一些,也為未來的不確定性留下了一定的緩沖空間。最終的選擇,往往是團(tuán)隊(duì)技術(shù)棧、項(xiàng)目需求和個人偏好綜合權(quán)衡的結(jié)果。

以上就是@Autowired 和 @Resource 注解的區(qū)別是什么?的詳細(xì)內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章!

最佳 Windows 性能的頂級免費(fèi)優(yōu)化軟件
最佳 Windows 性能的頂級免費(fèi)優(yōu)化軟件

每個人都需要一臺速度更快、更穩(wěn)定的 PC。隨著時間的推移,垃圾文件、舊注冊表數(shù)據(jù)和不必要的后臺進(jìn)程會占用資源并降低性能。幸運(yùn)的是,許多工具可以讓 Windows 保持平穩(wěn)運(yùn)行。

下載
來源:php中文網(wǎng)
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn
最新問題
開源免費(fèi)商場系統(tǒng)廣告
最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板
關(guān)于我們 免責(zé)申明 意見反饋 講師合作 廣告合作 最新更新
php中文網(wǎng):公益在線php培訓(xùn),幫助PHP學(xué)習(xí)者快速成長!
關(guān)注服務(wù)號 技術(shù)交流群
PHP中文網(wǎng)訂閱號
每天精選資源文章推送
PHP中文網(wǎng)APP
隨時隨地碎片化學(xué)習(xí)
PHP中文網(wǎng)抖音號
發(fā)現(xiàn)有趣的

Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號