DI(依存性注入)とSpringコンテナの仕組みを徹底解説!
こんにちは。ゆうせいです。
Spring Bootを使って開発していると、@Autowired
をよく見かけますよね?
この @Autowired
は DI(依存性注入: Dependency Injection) という仕組みの一部です。
では、DIとは何でしょうか?
また、Springコンテナ(Spring IoCコンテナ)がどのようにDIを実現しているのでしょうか?
今回は、これらの基本をわかりやすく解説します!
1. 依存性とは?
プログラムを書くとき、多くのクラスが他のクラスに依存して動作します。たとえば、以下のような UserService
と UserRepository
があったとします。
public class UserService {
private UserRepository userRepository;
public UserService() {
this.userRepository = new UserRepository();
}
public void getUser() {
userRepository.findUser();
}
}
public class UserRepository {
public void findUser() {
System.out.println("ユーザー情報を取得");
}
}
UserService
の中で UserRepository
のインスタンスを直接作成(new UserRepository()
)しています。
これは 「UserService は UserRepository に強く依存している」 状態です。
このように、あるクラスが別のクラスのインスタンスを直接生成することを 「依存関係がある」 と言います。
2. 依存性の問題点
上記の UserService
にはいくつかの問題があります。
- 変更しにくい
UserRepository
の実装を変えたくても、UserService
のコードも変更しなければなりません。- たとえば、
UserRepository
の代わりにMockUserRepository
を使いたい場合、直接コードを書き換える必要があります。
- テストしにくい
UserService
をテストしようとしてもUserRepository
に依存しているため、テストが難しくなります。- たとえば、データベースにアクセスしないモック版の
UserRepository
を使いたくても、new UserRepository()
の部分が邪魔になります。
- コードの再利用がしにくい
UserRepository
を他のクラスで使いたくても、UserService
の中に組み込まれているため再利用しにくくなります。
3. 依存性注入(DI)とは?
依存性注入(Dependency Injection: DI)は、クラスの中で new
して依存先のインスタンスを作るのではなく、外部から渡してもらう仕組み です。
UserService
に UserRepository
のインスタンスを コンストラクタ経由 で渡すように変更すると、次のようになります。
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void getUser() {
userRepository.findUser();
}
}
DIのポイント
UserService
の中でUserRepository
をnew
しなくなった。- 代わりに コンストラクタで
UserRepository
を受け取る ようになった。
こうすると、UserRepository
の実装を簡単に変更できるようになります。
UserRepository userRepository = new UserRepository();
UserService userService = new UserService(userRepository);
これで、UserService
は UserRepository
に依存しつつも、具体的な実装には依存しない ようになりました。
これは 「依存の方向を逆転させる(Dependency Inversion)」 という考え方です。
4. SpringのDIコンテナ
では、Spring Boot ではどうやって DI を実現するのでしょうか?
Spring には 「Springコンテナ(Spring IoCコンテナ)」 という仕組みがあり、これが DI を自動で管理してくれます。
IoCコンテナとは?
IoC(Inversion of Control: 制御の反転)とは、オブジェクトの作成や管理を 「自分でやるのではなく、フレームワークに任せる」 という考え方です。
Spring Boot では、Springコンテナ(IoCコンテナ)がアプリケーション全体のオブジェクト(Bean)を管理します。
5. Spring Boot でのDIの実装
Spring Boot では、アノテーションを使って簡単にDIを実現できます。
① Beanの登録
SpringでDIを使うためには、クラスを Bean(Springが管理するオブジェクト) として登録する必要があります。
例えば、UserRepository
をSpringの管理下に置くには @Repository
を使います。
import org.springframework.stereotype.Repository;
@Repository
public class UserRepository {
public void findUser() {
System.out.println("ユーザー情報を取得");
}
}
同様に、UserService を @Service でSpringに登録します。
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void getUser() {
userRepository.findUser();
}
}
② @Autowired
による依存性注入
Spring Bootでは、@Autowired
を使うと、依存するオブジェクトを自動で注入してくれます。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void getUser() {
userRepository.findUser();
}
}
Springコンテナが UserRepository
のインスタンスを自動的に作り、UserService
に渡してくれます。
これにより、new
する必要がなくなり、依存関係がすっきり整理されます。
6. DIのメリット
Spring Boot の DI には次のようなメリットがあります。
- 疎結合になる
UserService
はUserRepository
の実装を直接知らなくてもよくなる。- 例えば
MockUserRepository
に差し替えやすくなる。
- テストがしやすい
- 実際の
UserRepository
の代わりに、モックオブジェクトを渡せるため、ユニットテストがしやすくなる。
- 実際の
- 管理が楽
- SpringコンテナがすべてのBeanを管理するので、開発者が
new
する手間が省ける。
- SpringコンテナがすべてのBeanを管理するので、開発者が
まとめ
- DI(依存性注入) とは、オブジェクトの生成を外部から注入する仕組み。
- Springコンテナ(IoCコンテナ) がDIを自動で管理してくれる。
@Component
/@Service
/@Repository
を使うと、Springが自動でオブジェクトを管理する。@Autowired
を使うと、依存関係を自動で注入してくれる。
これを理解すれば、Spring Boot の柔軟で効率的な開発ができるようになります!
次は「Springのスコープ」や「DIの種類(フィールドインジェクション vs コンストラクタインジェクション)」について学ぶと、さらに理解が深まりますよ!
セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク
投稿者プロフィール

- 代表取締役
-
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。
最新の投稿
新入社員2025年2月21日【新人エンジニア必見】よくあるGitエラーメッセージと対策方法10選
新入社員2025年2月21日Spring BootのThymeleaf(タイムリーフ)入門 – テンプレートエンジンの基礎を学ぼう!
新入社員2025年2月21日【完全ガイド】良いJavaDocの書き方とベストプラクティス
新入社員2025年2月21日Spring Bootのアノテーションはなぜインタフェースなのか?