Springフレームワークでは、依存性注入を行う際に@Resourceや@Autowiredといったアノテーションを使用します。ただし、@ResourceはSpring固有のアノテーションではなく、javax.annotation.Resourceパッケージに属しています。Springはこのアノテーションをサポートしており、使用することができます。
共通点
どちらのアノテーションもフィールドやsetterメソッドに記述可能です。これらをフィールドに記述する場合、setterメソッドは省略できます。
違い
@Autowiredについて
@AutowiredはSpringが提供するアノテーションで、org.springframework.beans.factory.annotation.Autowiredパッケージからインポートされます。このアノテーションはbyType(型による)注入を行います。
以下は@Autowiredを使用した例です。
public class TestService {
// フィールドに直接指定
@Autowired
private UserRepository userRepo;
// setterメソッドに指定
@Autowired
public void setUserRepository(UserRepository userRepo) {
this.userRepo = userRepo;
}
}
@Autowiredはデフォルトで依存オブジェクトが存在することを前提としており、必須でない場合はrequired属性をfalseに設定します。また、byNameでの注入が必要な場合には@Qualifierアノテーションを併用します。
public class TestService {
@Autowired
@Qualifier("userRepo")
private UserRepository userRepo;
}
@Resourceについて
@ResourceはJ2EE標準のアノテーションであり、javax.annotation.Resourceパッケージに含まれます。このアノテーションにはnameとtypeという重要な属性があります。Springでは、@Resourceのname属性がbean名、type属性がbeanの型として解釈されます。name属性を使用するとbyName戦略、type属性を使用するとbyType戦略が採用されます。どちらの属性も指定しない場合、反射を利用してbyName戦略が適用されます。
以下は@Resourceを使用した例です。
public class TestService {
// フィールドに指定
@Resource(name="userRepo")
private UserRepository userRepo;
// setterメソッドに指定
@Resource(name="userRepo")
public void setUserRepository(UserRepository userRepo) {
this.userRepo = userRepo;
}
}
setterメソッドに@Resourceを配置するのが推奨される理由としては、オブジェクト指向の原則に基づき、属性への直接アクセスを避けるためです。
@Resourceの挙動は以下の順序で動作します:
- nameとtypeの両方が指定されている場合、Springコンテキスト内に一致するbeanが唯一であることを確認し、それ以外の場合例外をスローします。
- nameが指定されている場合、その名称(id)に一致するbeanを探します。見つからない場合、例外をスローします。
- typeが指定されている場合、型が一致する唯一のbeanを探します。複数または存在しない場合、例外をスローします。
- nameもtypeも指定されていない場合、まずbyName方式で検索を行い、一致しなければ基本的な型マッチングを行います。
結論として、@ResourceはデフォルトでbyName方式、一方@AutowiredはbyType方式で依存性を注入します。