@Component, @Service, @Repository の基本を解説!初心者でもわかるSpringのアノテーション
新人
「Spring Bootでよく出てくる @Component、@Service、@Repository って何ですか?」
先輩
「これらはSpringのアプリケーションで重要な役割を持つアノテーションで、それぞれ特定の用途に使われます。」
新人
「どのように使い分けるんですか?」
先輩
「それでは、@Component、@Service、@Repository の基本から解説していきましょう!」
1. @Component, @Service, @Repositoryとは?
Spring Bootでは、オブジェクトをSpringの管理下に置き、依存性注入(DI)を利用することで、効率的に開発を進めることができます。
そのために使われるのが、@Component、@Service、@Repository です。
- @Component - 一般的なコンポーネントを示す
- @Service - ビジネスロジックを持つクラスを示す
- @Repository - データベースとのやり取りを行うクラスを示す
これらのアノテーションを適切に使い分けることで、コードの可読性が向上し、役割ごとに整理されたアプリケーションを開発できます。
2. それぞれのアノテーションの役割と違い
@Componentの役割
@Component は、Springのコンポーネントとして管理されるクラスを示します。
例えば、以下のように @Component を付けたクラスは、Springの管理下に置かれます。
import org.springframework.stereotype.Component;
@Component
public class SampleComponent {
public String getMessage() {
return "これは @Component の例です";
}
}
このクラスは、Spring Bootが起動時に自動的にスキャンして登録するため、@Autowired などで簡単に利用できます。
@Serviceの役割
@Service は、ビジネスロジックを実装するクラスに使われます。
例えば、以下のように @Service を付けることで、Springがビジネスロジックのクラスとして認識します。
import org.springframework.stereotype.Service;
@Service
public class SampleService {
public String process() {
return "これは @Service の例です";
}
}
基本的には @Component と同じ動作をしますが、ビジネスロジック用のクラスであることを明示するために @Service を使用するのが一般的です。
@Repositoryの役割
@Repository は、データベースとやり取りを行うクラスに使われます。
例えば、以下のように @Repository を付けることで、Springがデータアクセス用のクラスとして認識します。
import org.springframework.stereotype.Repository;
@Repository
public class SampleRepository {
public String fetchData() {
return "これは @Repository の例です";
}
}
@Repository を付けることで、Springがデータアクセス関連のエラーハンドリングを自動で行うようになります。
3つのアノテーションの違い
以下の表に、それぞれの違いをまとめました。
| アノテーション | 用途 | 主な使用例 |
|---|---|---|
@Component |
一般的なコンポーネント | ユーティリティクラス、カスタムBean |
@Service |
ビジネスロジック | ユーザー処理、業務ロジック |
@Repository |
データアクセス層 | データベース操作(JPA、JDBC) |
このように、それぞれのアノテーションには役割がありますので、適切に使い分けることが重要です。
3. @Componentの詳細と使い方
@Component は、Springの管理下に置くべき一般的なコンポーネントを示します。特定の用途に限定されないため、ユーティリティクラスや共通機能を持つクラスなどに使われます。
@Componentの基本的な使用例
以下のように @Component を付与することで、Springのコンテナがこのクラスを管理します。
import org.springframework.stereotype.Component;
@Component
public class SampleComponent {
public String getMessage() {
return "これは @Component のサンプルです";
}
}
このクラスを別のクラスで利用する場合、@Autowired を使用すると、自動的にインスタンスが注入されます。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class SampleController {
private final SampleComponent sampleComponent;
@Autowired
public SampleController(SampleComponent sampleComponent) {
this.sampleComponent = sampleComponent;
}
public void execute() {
System.out.println(sampleComponent.getMessage());
}
}
このように @Component を付けたクラスは、Springの管理下に置かれ、DI(依存性注入)によって利用できるようになります。
4. @Serviceの詳細と使い方
@Service は、ビジネスロジックを担当するクラスに付与するアノテーションです。基本的には @Component と同じ動作をしますが、「このクラスはビジネスロジックを持つ」という意味を明示するために使います。
@Serviceの基本的な使用例
例えば、以下のように @Service を付けることで、Springがこのクラスをビジネスロジックを担当するコンポーネントとして認識します。
import org.springframework.stereotype.Service;
@Service
public class SampleService {
public String process() {
return "ビジネスロジックを実行しました";
}
}
この SampleService を Controller クラス内で利用するには、次のように @Autowired で注入します。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class SampleController {
private final SampleService sampleService;
@Autowired
public SampleController(SampleService sampleService) {
this.sampleService = sampleService;
}
public void execute() {
System.out.println(sampleService.process());
}
}
@Service を使用することで、ビジネスロジックの処理を一元管理でき、アプリケーションの保守性が向上します。
5. @Repositoryの詳細と使い方
@Repository は、データベースとのやり取りを行うクラスに付与するアノテーションです。JPA(Java Persistence API)やJDBCを利用する際に、データアクセス層のクラスに適用されます。
@Repositoryの基本的な使用例
以下のように @Repository を付与することで、Springがデータアクセス層のコンポーネントとして管理します。
import org.springframework.stereotype.Repository;
@Repository
public class SampleRepository {
public String fetchData() {
return "データベースからデータを取得しました";
}
}
このクラスを @Service クラスで利用することで、データベースアクセスの処理を分離し、より構造化されたアプリケーションを作成できます。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SampleService {
private final SampleRepository sampleRepository;
@Autowired
public SampleService(SampleRepository sampleRepository) {
this.sampleRepository = sampleRepository;
}
public String process() {
return sampleRepository.fetchData();
}
}
この SampleService を Controller クラスで利用すると、以下のようになります。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class SampleController {
private final SampleService sampleService;
@Autowired
public SampleController(SampleService sampleService) {
this.sampleService = sampleService;
}
public void execute() {
System.out.println(sampleService.process());
}
}
このように @Repository を使うことで、データアクセスの処理を分離し、アプリケーション全体の構造を整理できます。
@Repositoryのメリット
@Repository には、Springのデータアクセス層におけるエラーハンドリングを簡単にするメリットがあります。
例えば、データベースに接続できない場合やSQLエラーが発生した場合、Springは自動的に適切な例外をスローし、エラーハンドリングをサポートします。
6. @Autowiredを使った依存性注入(DI)の活用方法
Spring Bootでは、@Autowired を使ってクラス間の依存関係を管理することができます。これは依存性注入(DI: Dependency Injection)と呼ばれ、オブジェクトの作成や管理をSpringに任せることで、コードの保守性を向上させます。
@Autowiredを使った基本的なDIの仕組み
例えば、@Service クラスのインスタンスを @Controller に注入する場合、以下のように @Autowired を使用します。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class SampleController {
private final SampleService sampleService;
@Autowired
public SampleController(SampleService sampleService) {
this.sampleService = sampleService;
}
public void execute() {
System.out.println(sampleService.process());
}
}
上記のコードでは、SampleService のインスタンスが自動的に SampleController に注入されます。
フィールドインジェクションとコンストラクタインジェクション
依存性注入にはいくつかの方法がありますが、Spring Bootではコンストラクタインジェクションが推奨されています。
フィールドインジェクション
フィールドに直接 @Autowired を付与する方法です。
@Controller
public class SampleController {
@Autowired
private SampleService sampleService;
public void execute() {
System.out.println(sampleService.process());
}
}
この方法は簡単ですが、テストが難しくなるため、コンストラクタインジェクションの方が推奨されます。
コンストラクタインジェクション
コンストラクタ経由で依存性を注入する方法です。
@Controller
public class SampleController {
private final SampleService sampleService;
@Autowired
public SampleController(SampleService sampleService) {
this.sampleService = sampleService;
}
public void execute() {
System.out.println(sampleService.process());
}
}
コンストラクタインジェクションを使うことで、オブジェクトの作成時に依存関係が正しく設定されるため、テストしやすくなります。
7. 3つのアノテーションを組み合わせた実践的な使い方
ここまでに解説した @Component、@Service、@Repository を組み合わせて、実際にSpring Bootのアプリケーションでどのように使用するのかを見ていきましょう。
データ取得の流れ
以下のようなアプリケーションを作成します。
@Repositoryでデータ取得の処理を実装@Serviceでビジネスロジックを実装@Controllerで画面からのリクエストを処理
@Repository - データアクセス層
import org.springframework.stereotype.Repository;
@Repository
public class UserRepository {
public String findUser() {
return "ユーザー情報を取得しました";
}
}
@Service - ビジネスロジック層
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 String getUserInfo() {
return userRepository.findUser();
}
}
@Controller - プレゼンテーション層
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
private final UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
public void showUser() {
System.out.println(userService.getUserInfo());
}
}
このように、@Component、@Service、@Repository を適切に組み合わせることで、アプリケーションの役割分担を明確にし、保守性を向上させることができます。
8. Spring Bootのコンポーネントスキャンとアノテーションの関係
Spring Bootは、クラスパスをスキャンし、自動的に @Component、@Service、@Repository の付いたクラスを検出します。この仕組みをコンポーネントスキャンと呼びます。
@ComponentScanを使ったカスタマイズ
通常、Spring Bootのメインクラスに @SpringBootApplication を付与するだけで、コンポーネントスキャンが有効になりますが、手動でスキャン範囲を指定することも可能です。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = "com.example")
public class SampleApplication {
public static void main(String[] args) {
SpringApplication.run(SampleApplication.class, args);
}
}
このように @ComponentScan を使うことで、特定のパッケージのみをスキャン対象にすることができます。
コンポーネントスキャンの対象
Spring Bootのコンポーネントスキャンは、以下のアノテーションが付与されたクラスを自動的に登録します。
@Component@Service@Repository@Controller
適切にこれらのアノテーションを付与することで、Spring Bootの自動設定機能を活かしながら、簡単にアプリケーションを開発できます。
まとめ
今回の記事では、Spring Boot における @Component、@Service、@Repository の基本と役割の違い、
そして依存性注入やコンポーネントスキャンといった仕組みの流れを体系的に確認しました。
それぞれのアノテーションは似ているようで明確に用途が区別されており、アプリケーション構造を整理するうえで欠かせない存在です。
とくに、ビジネスロジックを担う @Service、データアクセスを担う @Repository の役割を明示することで、
後からコードを読む際の見通しがぐっと良くなります。
また、@Autowired を使った依存性注入が自然な流れで行われることで、クラス間のつながりが滑らかになり、
Spring の強みである開発効率と構造化されたアプリケーション設計の良さを体感できる内容でした。
実際の開発現場でもコンポーネントスキャンの仕組みによって、パッケージ構成さえ整理しておけば、
さまざまなクラスを自動で検出してくれるため、設定ファイルに大量の定義を書く必要がなくなります。
これによってクリーンで分かりやすいディレクトリ構造を保ちやすくなり、拡張性も高まっていきます。
とくに初心者にとっては、アノテーションを付けた瞬間に Spring が自動で管理してくれるという流れが最初は不思議に感じられますが、
仕組みを知ると納得できるようになり、より高度な機能にもスムーズに取り組めるようになります。
ここでは実際のプロジェクト風に、今回学んだ内容を振り返るサンプルプログラムも紹介しておきます。
サンプルプログラムの振り返り
アプリケーション全体の流れを一つにまとめた例です。
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.stereotype.Repository;
@Component
public class LogComponent {
public void printLog() {
System.out.println("共通処理を実行しました");
}
}
@Repository
public class ProductRepository {
public String load() {
return "商品データを取得しました";
}
}
@Service
public class ProductService {
private final ProductRepository repository;
private final LogComponent log;
public ProductService(ProductRepository repository, LogComponent log) {
this.repository = repository;
this.log = log;
}
public String execute() {
log.printLog();
return repository.load();
}
}
このように、役割ごとにアノテーションを付け、必要なクラスを依存性注入によって組み合わせることで、 Spring らしいなめらかで拡張性の高い設計が実現できます。 それぞれの配置や注入の流れは一見複雑に見えても、実際にはシンプルな規則で動いているため、 慣れてしまえば自然と書けるようになり、より大規模なアプリケーションにも応用できます。
生徒:「今日学んだ @Component、@Service、@Repository の違い、ようやく整理できた気がします!」
先生:「うん、それぞれの意味が分かると Spring の流れがつかみやすくなるよ。特に用途を明確に分けると後から読みやすくなるんだ。」
生徒:「たしかに、ビジネスロジックは @Service、データアクセスは @Repository って覚えておくとコードの見通しが良くなりますね。」
先生:「その調子。コンポーネントスキャンや依存性注入とつながると、Spring の全体像がもっとクリアになるよ。」
生徒:「次は実際のプロジェクトでも積極的に使ってみたいです!」
先生:「ぜひやってみるといい。実践が一番の習得方法だからね。」