@Autowired(Spring 專屬)與 @Resource(JSR-250 標準)皆可實現 Bean 裝配,但預設策略、屬性語義、優先級差異顯著,選型直接影響維護性與框架耦合度。
| 維度 | @Autowired | @Resource |
|---|---|---|
| 來源 | Spring Framework | JSR-250 (Java EE 標準) |
| 預設策略 | byType:按類型匹配 | byName:按 Bean 名稱匹配 |
| 指定名稱 | 需搭配 @Qualifier("name") | 直接用 @Resource(name="beanName") |
| 指定類型 | 原生支援 @Autowired @Qualifier(type) 較繁瑣 | @Resource(type=Xxx.class) |
| 允許 null | @Autowired(required=false) | 無對應屬性,需配合 @Autowired 或 Java 8 Optional |
| 作用位置 | 欄位、建構子、Setter、方法參數 | 欄位、Setter |
name + type → 唯一匹配該名稱且類型的 Bean,否則拋異常。name → 依名稱查找,找不到拋異常。type → 依類型查找唯一 Bean,找不到或多個皆拋異常。// 1. 建構子注入(推薦,不可變、易測試)
@Autowired
public OrderService(@Qualifier("vipRepo") UserRepository repo) { ... }
// 2. 多實例集合注入
@Autowired
private List strategies; // 注入所有 PaymentStrategy Bean
// 3. Map 注入:key=Bean名, value=Bean實例
@Autowired
private Map dataSources;
// 4. 可選注入
@Autowired(required=false)
private Optional extSvc; // Java 8+ 推薦用 Optional
@Resource
@Qualifier,代碼更乾淨。@Autowired 的場景
required=false 或 Optional 語義時。@Bean 方法參數)。@Autowired 直接報 NoUniqueBeanDefinitionException;@Resource 若欄位名恰好匹配其中一個 Bean 名稱則裝配成功,否則同樣報錯。@Resource(name="xxx") 指定名稱但 Bean 不存在 → 啟動拋異常,不會 回退 byType。總結:欄位注入首選 @Resource,建構子/集合/可選注入用 @Autowired。堅持標準、降低耦合、語義清晰,是長期可維護代碼的關鍵。