Quarkusの依存性注入(DI)とCDI基本アノテーションを初心者向けに徹底解説
生徒
「Quarkusって軽くて速いって聞いたんですが、DIとかCDIって何をするものなんですか?」
先生
「Quarkusでは、プログラムの部品同士を自動でつなげる仕組みとして、DIとCDIが使われています。自分でnewしなくても必要なクラスを使えるのが特徴です。」
生徒
「newを書かなくていいって、どういうことですか?」
先生
「Quarkusが代わりにオブジェクトを作って管理してくれるんです。基本アノテーションを理解すると、とても書きやすくなりますよ。」
1. QuarkusにおけるDIとCDIの考え方
Quarkusでは、依存性注入とCDIという仕組みを使って、クラス同士のつながりを自動的に管理します。依存性注入とは、あるクラスが必要とする別のクラスを、自分で作らず外から渡してもらう考え方です。Quarkusではこの役割をフレームワークが担当します。
CDIはJava標準の仕組みで、Quarkusはこれを高速かつ軽量に利用できるよう最適化しています。初心者にとっては、部品を組み立てる作業を自動化してくれる便利な機能だと考えると理解しやすいです。
2. @ApplicationScopedでアプリ全体に一つだけ作る
@ApplicationScopedは、アプリケーション全体で一つだけインスタンスを作り、それを使い回すためのアノテーションです。設定情報や共通処理をまとめたクラスでよく使われます。Quarkus起動時に一度だけ作られ、終了まで保持されます。
無駄なオブジェクト生成を防げるため、メモリ効率が良く、Quarkusの高速起動とも相性が良いのが特徴です。
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class GreetingService {
public String hello() {
return "Hello Quarkus";
}
}
3. @Injectで必要なクラスを自動的に使う
@Injectは、DIを行うための最も基本的なアノテーションです。これを付けることで、Quarkusが自動的に必要なクラスを探してセットしてくれます。自分でnewを書く必要がなくなり、コードがすっきりします。
初心者は、部品を自分で用意するのではなく、必要な場所で宣言するだけで使える点を意識すると理解しやすいです。
import jakarta.inject.Inject;
public class GreetingController {
@Inject
GreetingService service;
public String output() {
return service.hello();
}
}
4. @Singletonと@ApplicationScopedの違い
@Singletonも一つだけインスタンスを作る点では似ていますが、CDI管理という点で違いがあります。Quarkusでは基本的に@ApplicationScopedを使うことが推奨されます。CDIの機能をフルに活用でき、将来的な拡張にも対応しやすいからです。
初心者は、まず@ApplicationScopedを使うと覚えておくと混乱しにくくなります。
import jakarta.inject.Singleton;
@Singleton
public class TimeService {
public long now() {
return System.currentTimeMillis();
}
}
5. @RequestScopedでリクエストごとに管理する
@RequestScopedは、HTTPリクエストごとに新しいインスタンスを作るアノテーションです。Webアプリケーションでは、ユーザーごとやリクエスト単位で状態を分けたい場合があります。
QuarkusのREST APIと組み合わせると、リクエスト単位で安全にデータを扱えるようになります。
import jakarta.enterprise.context.RequestScoped;
@RequestScoped
public class RequestInfo {
public String info() {
return "request scope data";
}
}
6. コンストラクタインジェクションの基本
Quarkusでは、フィールドだけでなくコンストラクタを使った依存性注入も可能です。コンストラクタインジェクションは、必要な依存関係が明確になり、テストもしやすいというメリットがあります。
最初は少し難しく感じますが、クラス設計の理解が深まるため、慣れておくと役立ちます。
import jakarta.inject.Inject;
public class CalcService {
private final TimeService timeService;
@Inject
public CalcService(TimeService timeService) {
this.timeService = timeService;
}
public long calc() {
return timeService.now();
}
}
7. QuarkusでDIを使うメリット
Quarkusで依存性注入を使うと、コードの見通しが良くなり、修正や追加が簡単になります。部品ごとに役割が分かれるため、初心者でも全体構造を把握しやすくなります。
また、GraalVM対応や高速起動といったQuarkusの特徴とも相性が良く、実務でも使いやすい設計になります。