ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
DI(依存性注入)とは
DI(Dependency Injection)は、あるオブジェクトが他のオブジェクト(依存物)を必要とするとき、自分で生成せず外部から渡してもらう設計パターンです。「依存性注入」と訳されます。
DI を使うと、コンポーネント同士の結合度が下がり、ユニットテストでモックに差し替えたり、実装を入れ替えたりが容易になります。Java の Spring / CDI、.NET の Microsoft.Extensions.DependencyInjection、Angular / NestJS など、現代のフレームワークの多くが DI を中核機能として備えています。
DI なしのコード
public class OrderService {
private final MailSender mailSender;
public OrderService() {
// 自分で実装を選んで new
this.mailSender = new SmtpMailSender("smtp.example.com");
}
public void placeOrder(Order order) {
// ...
mailSender.send(order.getEmail(), "注文を受け付けました");
}
}
問題点:
- テストでモックに差し替えられない — テストでも本物の SMTP に送信してしまう
- 別の MailSender(SES、SendGrid 等)に変えるのが困難
- 結合度が高く、SmtpMailSender が無いとそもそもコンパイルできない
DI ありのコード(コンストラクタ注入)
public class OrderService {
private final MailSender mailSender;
// 依存物は外から受け取る
public OrderService(MailSender mailSender) {
this.mailSender = mailSender;
}
public void placeOrder(Order order) {
// ...
mailSender.send(order.getEmail(), "注文を受け付けました");
}
}
// 呼び出し側
MailSender sender = new SmtpMailSender("smtp.example.com");
OrderService service = new OrderService(sender);
// テスト時はモックを渡せる
OrderService service = new OrderService(new MockMailSender());
3 種類の注入方法
1. コンストラクタ注入(推奨)
public class OrderService {
private final MailSender mailSender;
public OrderService(MailSender mailSender) {
this.mailSender = mailSender;
}
}
メリット: 不変(final)で安全、必須依存が明確、テストしやすい。
2. セッター注入
public class OrderService {
private MailSender mailSender;
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}
}
メリット: オプショナルな依存を表現しやすい。デメリット: 注入忘れの NPE リスク。
3. フィールド注入(非推奨)
public class OrderService {
@Autowired
private MailSender mailSender; // フレームワーク依存
}
デメリット: フレームワーク無しでは動かない、final にできない、テストしにくい。Spring も現在はコンストラクタ注入を推奨。
Spring Framework での DI
@Service
public class OrderService {
private final MailSender mailSender;
public OrderService(MailSender mailSender) { // 自動的に注入
this.mailSender = mailSender;
}
}
@Component
public class SmtpMailSender implements MailSender {
@Override
public void send(String to, String body) { /* ... */ }
}
Spring が起動時に @Service や @Component を持つクラスをスキャンし、コンストラクタの引数型に合うインスタンスを自動で渡してくれます。
CDI(Jakarta EE)での DI
@ApplicationScoped
public class OrderService {
@Inject
private MailSender mailSender; // フィールド注入
public void placeOrder(Order order) {
mailSender.send(order.getEmail(), "受付完了");
}
}
DI と IoC の関係
| 用語 | 意味 |
|---|---|
| IoC(Inversion of Control) | 制御の反転。「呼ぶ側ではなく呼ばれる側が制御する」 |
| DI(Dependency Injection) | IoC の具体的な実現方法のひとつ |
| DI コンテナ | 依存解決を自動化するフレームワーク(Spring 等) |
メリット
- テスト可能性: モック / スタブに容易に差し替え可能
- 差し替え容易性: 実装変更が呼び出し側に波及しない
- SoC(関心の分離): 「使う」と「作る」が分離される
- DI コンテナでライフサイクル(シングルトン / リクエストスコープ等)を一元管理
デメリット / 注意点
- 学習コスト: フレームワーク特有の概念が多い
- スタックトレースが追いづらい: コンテナ層で抽象化される
- 過剰な抽象化: 小さなアプリで DI コンテナを使うとオーバーキル
DI が活躍する典型シーン
| シーン | 例 |
|---|---|
| 外部 API クライアント | 本番 API / テスト用モック |
| データベース層 | 本物 DB / インメモリ DB |
| メール送信 | SMTP / SES / ログ出力のみ |
| 時刻取得 | システム時刻 / 固定時刻(テスト用) |
| ロガー | 標準出力 / ファイル / リモートログ |
FAQ
Q: シングルトンパターンで十分では?
A: シングルトンはグローバル状態を生み、テストでモックに差し替えられません。DI のシングルトンスコープ(コンテナ管理)の方が、差し替え可能で安全です。
Q: DI コンテナを使わず手で new するのと違う?
A: 概念上の DI は手で new でも実現可能(Poor Man's DI)。コンテナの価値は大規模なオブジェクトグラフ管理とライフサイクル制御です。
Q: Spring と Guice、どちらを使うべき?
A: Web アプリ全般なら Spring(実質デファクト)、軽量に使いたいなら Guice。Java EE 環境なら CDI が標準。
関連
- IoC — 制御の反転
- Spring Framework — Java の代表的 DI コンテナ
- CDI — Jakarta EE 標準の DI 仕様
- Google Guice — Google 発の軽量 DI
- SOLID の D — 依存性逆転の原則(DIP)
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子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
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 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
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 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
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?