ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
CDI とは
CDI (Contexts and Dependency Injection for Java) は Jakarta EE 標準の DI(依存性注入)仕様です。Spring の @Autowired に相当するものを、Jakarta EE / MicroProfile の世界では CDI が担います。実装は Weld(WildFly/GlassFish)、OpenWebBeans(TomEE)等。
基本: @Inject
import jakarta.inject.Inject;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class UserService {
@Inject
private UserRepository repo; // フィールド注入
@Inject
private EmailSender sender;
public void register(String email) {
User u = new User(email);
repo.save(u);
sender.send(email, "welcome");
}
}
// コンストラクタ注入(推奨)
@ApplicationScoped
public class UserService {
private final UserRepository repo;
private final EmailSender sender;
@Inject
public UserService(UserRepository repo, EmailSender sender) {
this.repo = repo;
this.sender = sender;
}
}
スコープ
| スコープ | 有効範囲 | 用途 |
|---|---|---|
@ApplicationScoped | アプリ全体で 1 インスタンス | サービス、キャッシュ |
@SessionScoped | HTTP セッション | ログインユーザ情報 |
@RequestScoped | HTTP リクエスト | リクエストコンテキスト |
@ConversationScoped | 会話 (JSF 等) | ウィザード |
@Dependent (既定) | 注入先と寿命同じ | シンプルユーティリティ |
@SessionScoped + Serializable | 必須 |
@SessionScoped
public class UserContext implements Serializable {
private User user;
public User getUser() { return user; }
public void setUser(User u) { this.user = u; }
}
@RequestScoped
public class RequestId {
private final String id = UUID.randomUUID().toString();
public String get() { return id; }
}
@Qualifier で型を区別
同じインターフェースに複数実装があるとき、Qualifier で選択します。
import jakarta.inject.Qualifier;
import java.lang.annotation.*;
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})
public @interface Stripe {}
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})
public @interface PayPal {}
// 実装
@Stripe
@ApplicationScoped
public class StripeProcessor implements PaymentProcessor { ... }
@PayPal
@ApplicationScoped
public class PayPalProcessor implements PaymentProcessor { ... }
// 注入時に指定
@Inject @Stripe
private PaymentProcessor processor;
@Produces で外部依存を Bean 化
自分が書いていないクラス(外部 JAR、設定値)を Bean として登録できます。
import jakarta.enterprise.inject.Produces;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class AppConfig {
@Produces
public DataSource dataSource() {
HikariConfig cfg = new HikariConfig();
cfg.setJdbcUrl("jdbc:postgresql://localhost/app");
return new HikariDataSource(cfg);
}
@Produces @ApplicationScoped
public ObjectMapper jacksonMapper() {
return new ObjectMapper()
.registerModule(new JavaTimeModule())
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
@Produces
@ConfigValue("app.api.url")
public String apiUrl(InjectionPoint ip) {
return System.getenv("API_URL");
}
}
// 利用側
@Inject
private DataSource ds;
@Inject
private ObjectMapper json;
@Named とビューレイヤ連携
JSF や式言語 (EL) からアクセスできる名前を付けます。
import jakarta.inject.Named;
import jakarta.enterprise.context.SessionScoped;
@Named("userCtx") // EL: #{userCtx.user}
@SessionScoped
public class UserContext implements Serializable {
private User user;
public User getUser() { return user; }
public void setUser(User u) { this.user = u; }
}
Interceptor(AOP)
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Logged {}
@Interceptor
@Logged
@Priority(Interceptor.Priority.APPLICATION)
public class LoggingInterceptor {
@AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception {
long start = System.nanoTime();
try {
return ctx.proceed();
} finally {
long ms = (System.nanoTime() - start) / 1_000_000;
System.out.printf("[%s] %d ms%n", ctx.getMethod().getName(), ms);
}
}
}
// 利用
@Logged
public void register(String email) { ... }
Event Bus(疎結合通知)
// イベント定義
public class UserRegistered {
private final long userId;
public UserRegistered(long userId) { this.userId = userId; }
public long getUserId() { return userId; }
}
// 発火側
@ApplicationScoped
public class UserService {
@Inject Event<UserRegistered> event;
public void register(String email) {
User u = repo.save(new User(email));
event.fire(new UserRegistered(u.getId()));
// 4.0+ は event.fireAsync(...) で非同期
}
}
// 観察側(複数 OK、疎結合)
@ApplicationScoped
public class WelcomeEmailListener {
public void onUserRegistered(@Observes UserRegistered e) {
emailSender.send(e.getUserId(), "welcome");
}
}
@ApplicationScoped
public class AnalyticsListener {
public void onUserRegistered(@Observes UserRegistered e) {
analytics.track("signup", e.getUserId());
}
}
beans.xml と Bean 発見モード
| モード | 挙動 | 用途 |
|---|---|---|
all | すべての class を Bean 候補 | 古い CDI 1.0 互換 |
annotated | 明示的アノテーションのみ Bean 化(既定) | ★ 推奨 |
none | CDI 無効化 | パフォーマンス重視 |
<!-- META-INF/beans.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
version="4.0"
bean-discovery-mode="annotated">
</beans>
Spring DI との比較
| 機能 | CDI | Spring |
|---|---|---|
| 注入 | @Inject | @Autowired |
| Bean 定義 | @ApplicationScoped 等 | @Component / @Service |
| Producer / Factory | @Produces | @Bean |
| 条件付き | Extension SPI | @ConditionalOnXxx |
| スコープ | 標準 5 種類 | 標準 5 種類 + カスタム |
| イベント | Event<T> / @Observes | ApplicationEvent / @EventListener |
| インターセプタ | @InterceptorBinding | AspectJ / Pointcut |
| 標準 | Jakarta 仕様、複数実装 | Spring エコ実質単独 |
Jakarta CDI 4.x 主要変更点
- 名前空間:
javax.enterprise.*→jakarta.enterprise.* - 非同期 Observer (
@ObservesAsync) 強化 - Build-Time Compatible Extensions(Quarkus 向け軽量 SPI)
- SE モード(
CDI.current()でアプリ外から起動可能) - Bean 発見
annotatedがデフォルト
FAQ
Q: @Inject でなく @Autowired が使える?
A: Spring の中では使える。CDI / Jakarta EE の中では @Inject (JSR-330) が標準です。
Q: 循環依存はどうなる?
A: コンストラクタ注入では起動時にエラー。Provider<T> や Instance<T> で遅延注入して回避できます。
Q: テストでモック注入したい
A: Arquillian(実コンテナテスト)、Weld SE 単体テスト、または Mockito + コンストラクタ注入。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページ
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- IPv6とは|128bitアドレス・コロン16進表記/::省略・リンクローカル・SLAAC・デュアルスタック NEW 2026-06-22 12:34:44
- MAC アドレスフィルタリングの仕組みと限界 | ネットワーク入門 NEW 2026-06-22 12:19:10
- VPNとは|暗号トンネル・サイト間/リモートアクセス・IPsec/SSL-VPN/WireGuardを解説 NEW 2026-06-22 12:19:10
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/2 とは 多重化・HPACK・バイナリフレーム | ネットワーク入門 NEW 2026-06-22 12:17:25
- Web通信プロトコル入門 HTTP/2・HTTP/3・WebSocket・gRPC・WebRTC | ネットワーク入門 NEW 2026-06-22 12:17:25
- gRPC とは HTTP/2 + Protocol Buffers の高速 RPC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/3 (QUIC) とは UDP ベースの低遅延 Web 通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 NEW 2026-06-22 12:17:25
- 証明書と認証局(CA)とは|X.509・信頼チェーン・DV/OV/EV・失効(CRL/OCSP)を解説 NEW 2026-06-22 12:17:24
- ファイアウォールとは|パケットフィルタ・ステートフル・DMZ・次世代FW(L4/L7)を解説 NEW 2026-06-22 12:17:24
- iptables/nftablesとは|テーブル・チェーン・ルール例・永続化をLinux視点で解説 NEW 2026-06-22 12:17:24
- HAProxy とは frontend/backend と設定例 | ネットワーク入門 NEW 2026-06-22 12:17:24
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?