まえがき
研修でJavaEEを学んでいる中で、CDIのインジェクションに苦しみました。とりあえず、現時点で理解したところまでを備忘録として書き留めました。
CDIとは
簡単に言うと、newを使わずにインスタンス化する仕組みのことです。
Context and Dependency Injectionの略で、訳は「コンテキストと依存性注入」。
今回はDIの部分である依存性注入についてまとめます。
結局何がいいのか
- クラス間の依存関係を弱くしてくれる(疎結合に)
- テストしやすくなる
- インジェクトするクラスとされたクラスのスコープを互いに独立関係にできる
依存性注入
通常、とあるクラスで別のクラスのオブジェクトを使う場合、
Game.java
public class Game {
Tire dice = new Dice();
public void CreateGame(){
start(dice);
}
...
}
というようにnewを使ってインスタンス化する。そしてCarクラスとTireクラスには依存関係が生じる。
CDIを使うと、
Game.java
public class Game {
@Inject Dice dice; // CDIからインスタンス化
public void CreateGame(){
start(dice);
}
...
}
@Injectで変数car
にCarオブジェクト
を代入することができる。
tireについてのコンストラクタが含まれていない分、依存関係が弱くなるらしいが、ここがいまいちわからない。
疎結合により得られるメリット
例えば、Daoによりデータベースにアクセスする記事Webアプリを作るときに、
本番用ArticleDao
とテスト用ArticleTestDao
を使うとする。
通常であれば、テスト用Daoを使うときと本番用Daoを使うときとで、Daoを呼び出す部分で以下コメント部分を書き換えないといけない。
Article.java
public class Article {
ArticleDao articleDao = new ArticleDao(); // ここをArticleTestDaoに
return articleDao.findArticleById(id);
}
しかしCDIを使うと、テストと本番の切り替えは、呼び出したいDaoにスコープを付けるだけですむ。
呼び出し側のクラス名はそのままでよい。
ArticleTestDao.java
package dao;
@RequestScoped // 呼び出したいクラスにスコープを付ける
public class ArticleTestDao implements ArticleDao {
@Override
public void findArticleById() {
...
}
...
}