QuarkusのCDIスコープを完全理解!@ApplicationScopedと@RequestScopedを初心者向けに徹底解説
生徒
「QuarkusでDIとかCDIって出てくるんですが、スコープって何を意味しているんですか?」
先生
「スコープは、そのクラスのインスタンスが、いつ作られて、どのくらいの間使われるかを決める仕組みです。」
生徒
「@ApplicationScopedや@RequestScopedをよく見ますが、違いがよく分かりません。」
先生
「では、QuarkusとCDIの基本から順番に、初心者でもイメージできるように説明していきましょう。」
1. QuarkusとCDIの関係をざっくり理解しよう
Quarkusは、Javaで高速なWebアプリケーションやREST APIを作るためのフレームワークです。 Quarkusの大きな特徴の一つが、CDIという仕組みを使ったDIです。 CDIは、オブジェクトの生成や管理をフレームワークに任せるための仕組みで、プログラムを書く人は「何を使いたいか」だけを意識すればよくなります。 このCDIで重要になるのが、スコープという考え方です。 スコープを理解すると、Quarkusで書かれているコードの意味が一気に分かりやすくなります。
2. CDIスコープとは何かをイメージで考える
CDIスコープとは、そのクラスのインスタンスが「いつ作られ」「いつまで使われるか」を決めるルールです。 たとえば、アプリ全体で一つだけ使い回したいものもあれば、リクエストごとに新しく作りたいものもあります。 Quarkusでは、この違いをアノテーションで指定します。 初心者のうちは、まず「アプリ全体で一つ」か「アクセスごとに一つ」という感覚を持つことが大切です。
3. ApplicationScopedの基本的な考え方
ApplicationScopedは、アプリケーション全体で一つのインスタンスを使い回すスコープです。 Quarkusが起動したときに一度だけ作られ、アプリが終了するまで同じものが使われます。 設定情報や共通処理など、どこから呼ばれても同じでよい処理に向いています。 何度も新しく作られないので、パフォーマンスの面でもメリットがあります。
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class GreetingService {
public String hello() {
return "Hello Quarkus!";
}
}
このクラスは、アプリ全体で一つだけ作られ、何度リクエストが来ても同じインスタンスが使われます。 初心者のうちは「ずっと生きているクラス」と覚えると分かりやすいです。
4. RequestScopedの基本的な考え方
RequestScopedは、HTTPリクエストごとに新しく作られるスコープです。 Web画面を開いたり、REST APIを呼び出したりするたびに、新しいインスタンスが作られます。 一つのリクエストの中でだけ使われ、処理が終わると破棄されます。 ユーザーごとに違うデータを扱う場合に向いています。
import jakarta.enterprise.context.RequestScoped;
@RequestScoped
public class AccessLogService {
public String log() {
return "request accessed";
}
}
このクラスは、アクセスされるたびに新しく作られます。 同時に複数の人がアクセスしても、それぞれ別のインスタンスが使われるので安心です。
5. ApplicationScopedとRequestScopedの違いを比較する
ApplicationScopedは、アプリ全体で共有される一つのインスタンスです。 RequestScopedは、リクエスト単位で作られる一時的なインスタンスです。 たとえば、設定値を返すだけの処理はApplicationScopedが向いています。 一方で、リクエストの内容に応じて変わる処理はRequestScopedが適しています。 どちらを使うかは、「いつまでその情報を使いたいか」で考えると判断しやすくなります。
import jakarta.inject.Inject;
public class SampleResource {
@Inject
GreetingService greetingService;
@Inject
AccessLogService accessLogService;
public String execute() {
return greetingService.hello() + " / " + accessLogService.log();
}
}
6. 初心者がつまずきやすいポイントと注意点
初心者がよく迷うのが、どのスコープを使えばよいか分からない点です。 最初は、共通処理はApplicationScoped、リクエスト依存の処理はRequestScopedと覚えておけば問題ありません。 また、ApplicationScopedで状態を持つ場合は注意が必要です。 複数のリクエストから同時に使われるため、値を書き換える処理を書くと予期しない動きになることがあります。 まずは状態を持たないクラスとして使うのが安全です。
@ApplicationScoped
public class CounterService {
private int count = 0;
public int increment() {
count++;
return count;
}
}
このようなコードは、学習用としては理解しやすいですが、実際の開発では注意が必要です。 スコープの特性を意識することが、QuarkusとCDIを正しく使う第一歩になります。
まとめ
QuarkusのCDIスコープを理解する重要性
QuarkusにおけるCDIスコープの理解は、効率的で安全なアプリケーション開発に直結します。 特にApplicationScopedとRequestScopedの違いを正しく把握することで、無駄なインスタンス生成を防ぎ、パフォーマンスの向上やバグの予防につながります。 CDIは依存性注入の中心的な仕組みであり、その中でもスコープはインスタンスのライフサイクルを決定する非常に重要な概念です。 初心者の段階では難しく感じるかもしれませんが、アプリ全体で共有するのか、リクエスト単位で使い捨てるのかという視点で整理すると理解しやすくなります。
ApplicationScopedの特徴と使いどころ
ApplicationScopedはアプリケーション全体で一つのインスタンスを共有するスコープです。 そのため、設定情報や共通ロジックなど、どこから呼び出されても同じ結果になる処理に適しています。 一度だけ生成されるため、処理の効率が良く、メモリ使用量の削減にもつながります。 ただし、状態を持つ設計にすると複数のリクエストから同時にアクセスされるため、予期しない動作を引き起こす可能性があります。 そのため、基本的には状態を持たない設計を意識することが重要です。
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class ConfigService {
public String getAppName() {
return "Quarkus Sample App";
}
}
RequestScopedの特徴と使いどころ
RequestScopedはHTTPリクエストごとに新しいインスタンスが生成されるスコープです。 そのため、ユーザーごとの入力値や一時的な処理結果を扱うのに適しています。 リクエスト終了時に破棄されるため、状態管理がシンプルになり、安全にデータを扱うことができます。 WebアプリケーションやREST APIにおいては非常に利用頻度の高いスコープです。
import jakarta.enterprise.context.RequestScoped;
@RequestScoped
public class UserRequestService {
public String process(String user) {
return "Processing request for: " + user;
}
}
スコープ選択の考え方
スコープの選択は、データの寿命と利用範囲を基準に考えることが大切です。 アプリ全体で共有したい場合はApplicationScopedを選択し、リクエストごとに独立した処理を行いたい場合はRequestScopedを選びます。 この判断を誤ると、パフォーマンスの低下やバグの原因になるため、設計段階でしっかりと意識する必要があります。 特に初心者は、まずシンプルなルールで使い分けることをおすすめします。
import jakarta.inject.Inject;
public class ExampleResource {
@Inject
ConfigService configService;
@Inject
UserRequestService userRequestService;
public String execute() {
return configService.getAppName() + " - " + userRequestService.process("Taro");
}
}
初心者が理解しておきたいポイント
CDIスコープの理解で重要なのは、インスタンスの寿命と共有範囲を常に意識することです。 ApplicationScopedは長期間生存し、RequestScopedは短期間で破棄されるという違いを明確に覚えておくと混乱しません。 また、状態を持つかどうかという観点も重要であり、特にApplicationScopedではスレッドセーフな設計が求められます。 このような基本を押さえることで、Quarkusの開発効率は大きく向上します。
生徒
ApplicationScopedはアプリ全体で一つだけ使われるから効率がいいんですね。でも状態を持つと危ないというのが印象に残りました。
先生
その通りです。特に複数のリクエストが同時に来るWebアプリでは、共有インスタンスの扱いに注意が必要です。
生徒
RequestScopedはリクエストごとに新しく作られるので、安全にデータを扱えるという理解でいいですか。
先生
はい、その理解で問題ありません。ユーザーごとの処理や一時的なデータにはとても向いています。
生徒
つまり、共有したいものはApplicationScoped、リクエストごとに分けたいものはRequestScopedという考え方ですね。
先生
その判断基準を持っていれば、スコープ選びで迷うことは少なくなります。実際の開発でもとても役立つ考え方です。