@Configuration と @Bean の使い方を完全解説!Spring Bootの設定方法
新人
「Spring Bootの@Configurationと@Beanって何ですか?」
先輩
「Springでは、オブジェクトの管理を簡単にするために、@Configurationと@Beanを使うんだよ。」
新人
「それはDI(依存性注入)と関係があるんですか?」
先輩
「そうだね!SpringのDIを活用するために、@Configurationと@Beanはとても重要な役割を持っているよ。まずは、それぞれの基本的な役割を説明するね。」
1. @Configuration とは?
Spring Boot では、設定クラスを定義するために @Configuration を使用します。このアノテーションを付けたクラス内で @Bean を使うことで、Spring の DI コンテナにオブジェクトを登録できます。
例えば、次のように設定クラスを作成します。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyService();
}
}
この @Configuration を付けたクラス内で定義された @Bean は、Spring コンテナに登録され、必要な場所で自動的に利用できます。
2. @Bean とは?
@Bean は、Spring コンテナに管理させたいオブジェクトを定義するためのアノテーションです。
通常、Spring では @Component や @Service などのアノテーションを使ってオブジェクトを登録しますが、カスタムオブジェクトや外部ライブラリのオブジェクトを登録したい場合には @Bean を使います。
@Bean を使ったクラスの登録
例えば、独自のサービスクラスを Bean として登録する場合、次のように定義します。
public class MyService {
public String getMessage() {
return "こんにちは、Spring @Bean!";
}
}
そして、@Bean を使って Spring に登録します。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyService();
}
}
このように定義すると、Spring の DI 機能を使って MyService のインスタンスを必要な場所に注入できます。
3. @Configuration と @Bean を使った具体的な設定方法
実際に @Configuration と @Bean を使って、Spring の DI(依存性注入)を実現する方法を見ていきましょう。
1. まずは対象のクラスを用意する
例えば、データを提供するサービスクラス MyService を作成します。
public class MyService {
public String getMessage() {
return "こんにちは、Spring @Bean!";
}
}
2. @Configuration で Bean を定義する
次に、このサービスクラスを @Bean を使って Spring に登録します。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyService();
}
}
3. Bean を利用するクラスで注入する
最後に、MyService を Spring の DI を利用して注入し、活用します。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class MyController {
private final MyService myService;
@Autowired
public MyController(MyService myService) {
this.myService = myService;
}
public void showMessage() {
System.out.println(myService.getMessage());
}
}
このように、@Bean で登録したオブジェクトは、Spring の DI を活用して簡単に他のクラスへ注入できます。
4. @Bean を使うメリット(DIとの関係性)
@Bean を使うことには、以下のようなメリットがあります。
1. オブジェクトの管理を Spring に任せられる
Spring の DI コンテナが自動的にオブジェクトを生成・管理するため、開発者が手動でインスタンスを作成する必要がなくなります。
2. 保守性の向上
Spring がオブジェクトのライフサイクルを管理するため、不要になったオブジェクトの破棄も容易になります。
3. モックを簡単に差し替え可能
テスト時に異なる実装を簡単に差し替えられるため、柔軟なテストが可能になります。
4. Spring のコンポーネントスキャンを活用できる
@Bean は @Component より柔軟にカスタマイズ可能であり、外部ライブラリのクラスなども管理下に置くことができます。
5. Spring Boot での @Configuration と @Bean の活用例
Spring Boot のアプリケーション開発において、@Configuration と @Bean は以下のような場面で活用されます。
1. カスタム設定の定義
例えば、独自のオブジェクトを Spring に管理させたい場合に @Bean を使用できます。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CustomConfig {
@Bean
public String appName() {
return "Spring Boot Application";
}
}
この appName() メソッドで定義された Bean は、アプリケーション内で利用できます。
2. 外部ライブラリの Bean 登録
Spring の @ComponentScan の対象外のクラス(例えば外部ライブラリ)を Bean として管理したい場合にも @Bean を活用できます。
import com.example.library.SomeLibrary;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class LibraryConfig {
@Bean
public SomeLibrary someLibrary() {
return new SomeLibrary();
}
}
このように @Bean を使うことで、Spring が管理しない外部のオブジェクトも簡単に DI に組み込むことができます。
3. 複数の実装を使い分ける
同じインターフェースの異なる実装を @Bean で切り替えることも可能です。
public interface GreetingService {
String greet();
}
public class EnglishGreetingService implements GreetingService {
public String greet() {
return "Hello, Spring!";
}
}
public class JapaneseGreetingService implements GreetingService {
public String greet() {
return "こんにちは、Spring!";
}
}
設定クラスで実装を切り替える
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class GreetingConfig {
@Bean
public GreetingService greetingService() {
return new JapaneseGreetingService();
}
}
このように @Bean を使うことで、設定ファイルを変更するだけで、異なる実装に切り替えられます。
4. プロファイルによる Bean の切り替え
Spring Boot では、@Profile を使って環境に応じた Bean の切り替えも可能です。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
public class ProfileConfig {
@Bean
@Profile("dev")
public GreetingService devGreetingService() {
return new EnglishGreetingService();
}
@Bean
@Profile("prod")
public GreetingService prodGreetingService() {
return new JapaneseGreetingService();
}
}
この設定を行うと、アプリケーションの実行環境によって、異なる Bean を注入できます。
以上のように、@Configuration と @Bean は、Spring Boot のアプリケーションで柔軟な設定を可能にします。
6. @ComponentScan と @Bean の違い
Springでは、@ComponentScan と @Bean の両方を使ってBeanを登録できますが、それぞれの用途や特徴が異なります。
@ComponentScan の特徴
@ComponentScan は、Springが自動的に特定のパッケージ内のクラスをスキャンし、適切なアノテーション(@Component, @Service, @Repository, @Controller など)が付与されているクラスをSpringの管理対象Beanとして登録します。
import org.springframework.stereotype.Service;
@Service
public class UserService {
public String getUser() {
return "ユーザー情報を取得しました";
}
}
このように @Service を付けることで、@ComponentScan によって自動的にBeanとして登録されます。
@Bean の特徴
@Bean は、手動でSpringのDIコンテナにBeanを登録するために使用します。特に、外部ライブラリのクラスなど、直接 @Component や @Service を付与できない場合に便利です。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public UserService userService() {
return new UserService();
}
}
この方法を使うと、Springが管理するBeanとして UserService を登録し、必要な箇所で利用できます。
@ComponentScan と @Bean の使い分け
- @ComponentScan を使う場合: Springアノテーションを付与したクラスを自動で登録したいとき。
- @Bean を使う場合: 外部ライブラリのクラスや、特別な設定が必要なBeanを登録したいとき。
7. 実際の開発で @Bean を使うべきケース
実際の開発で @Bean を使用するべき代表的なケースを紹介します。
1. 外部ライブラリのオブジェクトを管理したい場合
例えば、外部のライブラリクラス(Springが管理していないクラス)をSpringのDIコンテナで管理したい場合、@Bean を使用できます。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.example.library.ExternalLibraryClass;
@Configuration
public class ExternalLibraryConfig {
@Bean
public ExternalLibraryClass externalLibraryClass() {
return new ExternalLibraryClass();
}
}
2. カスタムBeanの設定が必要な場合
Springの標準的なコンポーネントスキャンでは対応できない特殊な設定が必要な場合、@Bean を使って細かいカスタマイズが可能です。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
public class CustomConfig {
@Bean
public List<String> sampleList() {
return List.of("A", "B", "C");
}
}
3. プロファイルごとに異なる設定を適用したい場合
開発環境(dev)と本番環境(prod)で異なる設定を適用する場合、@Profile を使って切り替えが可能です。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
public class ProfileConfig {
@Bean
@Profile("dev")
public String devConfig() {
return "開発環境の設定";
}
@Bean
@Profile("prod")
public String prodConfig() {
return "本番環境の設定";
}
}
4. 依存関係のあるオブジェクトを手動で管理したい場合
例えば、複数のコンストラクタ引数が必要なオブジェクトをSpringに管理させたい場合、@Bean を利用すると便利です。
@Configuration
public class ServiceConfig {
@Bean
public OrderService orderService(ProductRepository productRepository) {
return new OrderService(productRepository);
}
}
このように、依存関係のあるオブジェクトを手動で管理しながら、SpringのDIを活用できます。
8. Spring Boot の学習を深めるためのおすすめの方法
Spring Boot の知識を深めるためには、実際の開発を通じて学ぶことが重要です。ここでは、学習に役立つ方法をいくつか紹介します。
1. 公式ドキュメントを活用する
Spring Boot の公式ドキュメントは非常に充実しており、最新の情報が得られます。
2. 小さなプロジェクトを作成して試す
実際にコードを書きながら学ぶことで、知識の定着が早くなります。
- 簡単なWebアプリケーションを作成してみる
- REST API を作成し、フロントエンドと連携させる
- データベースと接続し、CRUD処理を試してみる
3. 動画チュートリアルを視聴する
YouTube や Udemy などで Spring Boot の解説動画を視聴すると、理解が深まります。
4. 書籍を読む
Spring Boot に関する書籍を1冊読んでみると、体系的に学べます。
5. Spring Boot の公式サンプルコードを試す
Spring Boot は多くの公式サンプルを提供しているため、実際に試しながら学習できます。
以上のように、@Configuration と @Bean の理解を深めながら、Spring Boot の実践的な活用方法を学んでいきましょう!
まとめ
この記事では、Spring Boot の設定でよく登場する@Configuration と @Bean の役割や使い方、@ComponentScan や @Profile との違いまで、ひと通り流れに沿って確認しました。どちらも毎回のようにコードに書いているのに、なんとなく雰囲気だけで使っていたという人も多いので、一度整理しておくと今後の Spring 開発の理解がぐっと深くなります。あらためて振り返ると、設定クラスと DI コンテナ、そして Bean 定義の関係性が頭の中で一本の線でつながってきたのではないでしょうか。
まず大きなポイントは、@Configuration が「設定クラス」であり、@Bean が「コンテナに登録したいインスタンスを返すメソッド」であるという区別です。クラスに @Configuration を付けることで、そのクラスが Spring コンテナに対して Bean 定義を提供する場所になります。その中に定義した @Bean メソッドは、アプリケーション起動時に一度だけ呼び出され、戻り値のオブジェクトが Bean として登録されます。普段なんとなく見ている AppConfig などのクラスが、実はアプリ全体の部品表になっている、というイメージを持っておくと理解しやすくなります。
そして @Bean を使うときに意識したいのが「なぜコンストラクタ new で直接生成しないのか」という視点です。Spring の DI コンテナに Bean として登録しておけば、@Autowired やコンストラクタインジェクションを通じてどこからでも同じインスタンスを安全に利用できますし、テストコードでは別の実装クラスやモックに差し替えることも簡単です。特にサービスクラスやリポジトリクラスだけでなく、外部ライブラリのクライアントや共通設定オブジェクトなど、アプリ全体で共有したいものは Bean として管理しておくと、後から設計を見直したときに恩恵を感じる場面が多くなります。
また、記事の中で触れたように、@Component や @Service などのアノテーションで自動検出される Bean と、@Configuration 内で明示的に定義する @Bean は、目的が少し異なります。クラスそのものを Spring 管理下に置きたいときには @Component 系のアノテーションが便利ですが、「生成方法を細かく制御したい」「コンストラクタに渡す値を変えたい」「実装クラスを環境ごとに切り替えたい」といった場合には、設定クラスで @Bean を使って明示的に定義する方が分かりやすくなります。特に、既存ライブラリのクラスには @Component を付けられないので、そのようなときに @Bean が活躍します。
実装面では、@Configuration クラスの中で複数の Bean を組み立てるイメージを持つと理解が深まります。例えば、リポジトリを引数に取るサービスクラスを定義したい場合、設定クラスは次のような形になります。
@Configuration
public class ServiceConfig {
@Bean
public OrderService orderService(ProductRepository productRepository) {
return new OrderService(productRepository);
}
}
ここで引数に宣言されている ProductRepository もまた Bean として登録されているため、Spring が依存関係を解決してくれます。呼び出し側が意識しなくても、設定クラスの中で関係性を宣言しておくだけで、起動時に必要な順番でインスタンスが組み立てられる、というのが DI コンテナの大きな特徴です。設定が増えてきたら、ドメインごとや機能ごとに @Configuration クラスを分けていくと、構成も見通しやすくなります。
環境ごとに設定を変えたいときに便利なのが、記事後半で取り上げた @Profile との組み合わせです。開発環境では簡易的な実装、本番環境では本物の外部サービスを呼び出す実装、といった切り替えを、設定クラスの中で @Bean と @Profile を組み合わせるだけで表現できます。アプリケーションの起動引数や設定ファイルでアクティブプロファイルを変更するだけで、注入される Bean が自動的に切り替わるため、ビルド成果物を分けることなく、ひとつのプロジェクトで複数環境に対応できます。
もう一つ押さえておきたいのが、Spring Boot が提供している自動設定との付き合い方です。スターター依存関係を追加するだけで、データソースやメッセージコンバータなど、たくさんの Bean がすでに登録されていますが、自分で @Configuration と @Bean を定義することで、デフォルト設定を上書きしたり、足りない部分だけを補ったりできます。すべてを自前で書く必要はありませんが、「どの Bean がどこで定義されているのか」を意識しておくと、トラブルシューティングやチューニングのときに調査がしやすくなります。
実際の現場では、設定クラスの役割をドキュメントのように整理しておくことも大切です。たとえば「データベース周りの設定をまとめた DbConfig」「メッセージキュー関連をまとめた MessagingConfig」「ビューやテンプレート関連をまとめた WebConfig」といった具合に役割ごとに分けると、新しく参加したメンバーでもすぐに全体像をつかめます。クラス名やパッケージ構成を丁寧に設計することは、コードの読みやすさだけでなく、チーム開発の生産性にもつながります。
ここまでの内容を踏まえると、@Configuration と @Bean はどちらも「Spring Boot でアプリケーションをどう組み立てるか」を記述するための重要な道具だと分かります。学習を続ける際は、単にサンプルコードを写経するだけでなく、「なぜここでコンポーネントスキャンではなく @Bean が使われているのか」「この設定クラスはどんな責務を持っているのか」といった観点でコードを読み解いていくと、設計力やリファクタリングの感覚も自然と鍛えられていきます。
生徒
「きょうは@Configuration と @Bean の使い方をまとめてみて、今までぼんやりしていた部分がかなりはっきりしました。設定クラスの中で Bean を組み立てている、という考え方がいちばん印象に残りました。」
先生
「いい視点ですね。アプリケーションの土台になる部分なので、ここが理解できると Spring Boot 全体の見通しも良くなります。特に、外部ライブラリや設定値を Bean として登録しておくと、テストや将来の拡張もしやすくなる、という感覚は大事にしておくとよいですよ。」
生徒
「@ComponentScan で自動登録されるクラスと、@Bean で明示的に登録するクラスの違いも、ようやく整理できました。同じ Bean でも、どういう経路でコンテナに登録されるかが違うんですね。」
先生
「その通りです。たとえば外部サービスのクライアントや、環境ごとに実装を切り替えたいインターフェースなどは、設定クラスで @Bean として定義しておくと扱いやすくなります。逆に、ドメインサービスやコントローラのように、明確に役割が決まっているクラスは @Service や @Controller を付けて自動検出に任せる、といった使い分けを意識すると良いですね。」
生徒
「@Profile を組み合わせて Bean を切り替える例も、実務でそのまま使えそうだと感じました。開発環境ではスタブ、本番では本物のサービス、という切り替えが設定クラスだけで完結するのはとても便利ですね。」
先生
「プロファイルは覚えておくと本当に重宝しますよ。実際の現場でも、接続先やログ出力の設定を環境ごとに変えるときによく使われます。今回学んだ @Configuration と @Bean の知識と組み合わせれば、かなり柔軟な構成が組めるはずです。」
生徒
「これからは、チュートリアルのコードをそのまま使うだけでなく、『この Bean はどこで定義されているのか』『自分なら設定クラスをどう分けるか』ということも意識しながら Spring Boot のプロジェクトを読んでみようと思います。」
先生
「とても良い心がけです。設定クラスを理解することは、アプリケーションの構造そのものを理解することでもあります。少しずつ自分なりの書き方や分け方を試しながら、Spring Boot の設定と Bean 定義に慣れていきましょう。」