カテゴリ: Micronaut 更新日: 2026/01/30

Micronautのスコープまとめ!Singleton・Prototype・ThreadLocalを初心者向けに整理解説

Micronautのスコープまとめ!Singleton・Prototype・ThreadLocalを整理
Micronautのスコープまとめ!Singleton・Prototype・ThreadLocalを整理

先生と生徒の会話形式で理解しよう

生徒

「MicronautでDIを使っていると、SingletonとかPrototypeとか出てきて混乱します……」

先生

「Micronautでは、Beanがどのタイミングで作られて、どれくらい使い回されるかをスコープで決めています」

生徒

「スコープって、メモリの使われ方にも影響するんですか?」

先生

「影響します。特にSingletonとPrototypeの違いを理解すると、DI設計が一気に楽になります」

生徒

「ThreadLocalっていうのも見かけましたが、これは何ですか?」

先生

「では、Micronautのスコープを順番に整理しながら見ていきましょう」

1. Micronautにおけるスコープとは何か

1. Micronautにおけるスコープとは何か
1. Micronautにおけるスコープとは何か

Micronautのスコープとは、DIコンテナが管理するBeanの生成タイミングや生存期間を決める仕組みです。 JavaのDIフレームワークでは、同じクラスでも使い方によって生成回数を制御する必要があります。 Micronautではアノテーションを使うことで、Beanのライフサイクルを明確に指定できます。

特に初心者がつまずきやすいのが、常に一つだけ生成されるBeanと、使うたびに新しく生成されるBeanの違いです。 スコープを理解すると、DIエラーの回避やパフォーマンス改善にもつながります。

2. Singletonスコープの基本と特徴

2. Singletonスコープの基本と特徴
2. Singletonスコープの基本と特徴

SingletonはMicronautで最も基本となるスコープです。 アプリケーション全体で一つだけBeanが生成され、複数のクラスから同じインスタンスが共有されます。 特に状態を持たないサービスクラスや、共通処理をまとめたクラスに向いています。

Micronautでは特別な指定をしなくても、BeanはデフォルトでSingletonとして扱われます。 そのため、初心者は意識せずにSingletonを使っているケースがほとんどです。


import jakarta.inject.Singleton;

@Singleton
public class GreetingService {

    public String greet(String name) {
        return "こんにちは、" + name;
    }
}

上記のクラスはアプリケーション起動時に一度だけ生成され、DIによって使い回されます。 無駄なオブジェクト生成が発生しないため、パフォーマンス面でも優れています。

3. Prototypeスコープの仕組みと使いどころ

3. Prototypeスコープの仕組みと使いどころ
3. Prototypeスコープの仕組みと使いどころ

Prototypeスコープは、DIで注入されるたびに新しいインスタンスが生成されるスコープです。 毎回独立した状態を持たせたい場合に利用します。 リクエストごとに異なる値を保持するクラスなどに向いています。

Singletonと異なり、Prototypeは使い過ぎるとオブジェクト生成コストが増えるため注意が必要です。 役割を明確にした上で使い分けることが重要です。


import io.micronaut.context.annotation.Prototype;

@Prototype
public class RequestCounter {

    private int count = 0;

    public void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

このクラスはDIされるたびに新しいインスタンスが作られます。 他のクラスと状態を共有しないため、安全に使うことができます。

4. ThreadLocalスコープの考え方

4. ThreadLocalスコープの考え方
4. ThreadLocalスコープの考え方

ThreadLocalスコープは、スレッドごとにBeanのインスタンスを分けたい場合に利用します。 マルチスレッド環境で、スレッド単位の状態管理が必要な場面で活躍します。

Webアプリケーションでは、同時に複数のリクエストが処理されるため、 スレッド単位でデータを分離したいケースが存在します。


import io.micronaut.context.annotation.ThreadLocal;

@ThreadLocal
public class UserContext {

    private String userId;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }
}

ThreadLocalスコープは便利ですが、初心者のうちは無理に使う必要はありません。 まずはSingletonとPrototypeを正しく使い分けることが大切です。

5. スコープ選択を間違えたときのトラブル例

5. スコープ選択を間違えたときのトラブル例
5. スコープ選択を間違えたときのトラブル例

スコープを誤って選択すると、意図しないデータ共有や不具合の原因になります。 例えば、状態を持つクラスをSingletonにすると、複数処理でデータが上書きされる可能性があります。

逆に、すべてをPrototypeにすると、メモリ使用量が増加し、 パフォーマンス低下を招くこともあります。

MicronautのDI設計では、まずSingletonを基本とし、 明確な理由がある場合のみPrototypeやThreadLocalを選択する考え方が安全です。

6. 初心者向けスコープ使い分けの指針

6. 初心者向けスコープ使い分けの指針
6. 初心者向けスコープ使い分けの指針

初心者がMicronautで開発を進める場合、以下の考え方を意識すると理解しやすくなります。 共通処理やロジックはSingleton、状態を分離したい場合はPrototype、 スレッド単位の情報管理が必要なときだけThreadLocalを検討します。

スコープを意識して設計することで、DIエラーを減らし、 保守しやすいMicronautアプリケーションを構築できます。

関連記事:
カテゴリの一覧へ
新着記事
New1
Micronaut
Micronautの@Factoryとは?複雑なBean生成を管理するための方法を解説
New2
Quarkus
QuarkusのDIとCDIを完全理解!@Producesでプロデューサーメソッドを使う方法を初心者向けに解説
New3
Java
JavaのStringBufferクラスを徹底解説!スレッド安全な文字列操作の仕組みと使い分け
New4
Micronaut
Micronautで非同期HTTP処理を行う方法!リアクティブ対応の基礎知識
人気記事
No.1
Java&Spring記事人気No1
Quarkus
Quarkus入門!GitHub ActionsでCI/CDパイプラインを構築して自動ビルドを実現する方法
No.2
Java&Spring記事人気No2
Java
Javaのコンパイルと実行の流れを解説!JVM・JDK・JREの違いも初心者向けに整理
No.3
Java&Spring記事人気No3
Micronaut
Micronautのルーティング設定ガイド!プレフィックス付与とAPIバージョニングの基本
No.4
Java&Spring記事人気No4
Quarkus
QuarkusのCI/CD入門!GitHub Actionsで自動デプロイを実現する方法
No.5
Java&Spring記事人気No5
Micronaut
Micronautのフィルタ徹底解説!HTTPリクエスト共通処理をスマートに追加する方法
No.6
Java&Spring記事人気No6
Java
Java Optional ifPresentの使い方を徹底解説!nullチェックをスマートに省略する方法
No.7
Java&Spring記事人気No7
Java
Java Functionインタフェースの使い方を完全ガイド!map変換と処理チェーンを理解する
No.8
Java&Spring記事人気No8
Java
JavaのString比較を徹底解説!equalsと==の違い、初心者が陥る罠とは?