LoginSignup
4
1

More than 3 years have passed since last update.

【Java】Spring DI ①

Posted at

Spring DIは何をするの?

  • インスタンス管理をする
    • @Autowiredアノテーションをフィールドなどに付けると、DIコンテナからインスタンスを取得
    • DIによってクラスをnewしたり、使い終わった変数にnullを入れる必要がなくなる

DI の2つの機能

  • インスタンスの生成

    • DIコンテナの中で、インスタンスを生成=クラスをnew
    • アプリケーションではこのインスタンスを取得して利用
    • DIの中で、毎回newしたインスタンスをアプリケーションに渡すのか、それとも、一度newしたインスタンスをアプリケーションに渡すのかを管理
  • インスタンスのライフサイクル管理(インスタンスの破棄)

    • サーブレット(バックエンド)のリクエストスコープ (サーブレット、JSP間を跨いでデータを共有したい場合に用いる保存領域) や、セッションスコープにインスタンスを簡単に登録できる

Javaにおける依存って何?

  • 依存というのは、他のクラスを利用しているかどうか
    • 他のクラスをローカル変数として持っている
    • 他のクラスがメソッドの引数、戻り値になっている
  • 以下の例では車がエンジンを使うため、車クラスはホンダのエンジンクラスに依存していることになる
//車クラス
public classCar{
    //ホンダのエンジン
    private HondaEngine hondaEngine;
    //コンストラクタ
    public class Car(HondaEngine hondaEngine){
    //ホンダのエンジンをセット
    this.hondaEngine = hondaEngine;

    }
}
 //車を作る(=new)するMainクラス
public class Main{ 
    public static void main(String[]args){
    //パーツの生成
    HondaEngine hondaEngine = new HondaEngine();
    //車の生成
    Car car = new Car(hondaEngine);
    }
}

依存度合い

  • 密結合:依存度が高い状態
    • 上の例では別の会社のエンジンに変更したい場合、CarクラスとMainクラスの両方を修正する必要=密結合
    • 日産のエンジンクラスが完成してないとテストができない=変更に弱いアプリケーションになってしまっている。。
  • →インターフェースを使って結合度を下げる!

  • 車の部品を自由に交換できるようインターフェース作成

    • インターフェースを継承したクラスでは、これらのメソッドを必ず実装する必要
    • メソッド内に起動と停止時の具体的な処理をSBの記述


Engineインターフェース

//Engineインターフェース
public interface Engine {
    public void boot();//起動メソッド
    public void stop();//停止メソッド
}

Engineインターフェース実装クラス

//Engineインターフェースを継承したHondaEngineクラス
public class HondaEngine implements Engine {
    //コンストラクタ
    public HondaEngine(){
        super();
        }
        //起動メソッド
        @Override
        public void boot(){
            System.out.println("ホンダエンジン起動");
        }
        //停止メソッド
        @Override 
        public void stop(){
        System.out.println("ホンダエンジン停止");
        }
}

Carクラス

  • フィールド(データ)をインターフェースに変更
  • インターフェースの起動・停止メソッドを利用するメソッドを用意
public class Car{
    //エンジン
    private Engine engine;
    //コンストラクタ
    public Car(Engine engine){
        this.engine=engine;
    }
    //エンジンをかける
    public void engineStart(){
        engine.boot();
    }
    //エンジンをとめる
    public void engineStop(){
        engine.stop();
    }
}

Mainクラス

  • インターフェース型の変数には、それを継承したサブクラスのインスタンス(HondaEngine)を入れることが可能
//Engine型の変数にHondaEngineインスタンスを入れている
public class Main{
    public static void main(String[]args){
        //エンジンの生成(HondaEngine)
        Engine engine = new HondaEngine();
        //車クラスの生成
        Car car = new Car(engine);
        //エンジンをかける
        car.engineStart();
        //エンジンをとめる
        car.engineStop();
    }
}

クラス図

  • 車クラスはEngineインターフェースに依存、HondaEngineクラスには依存しない
  • →エンジン種類を変更したい場合、新しい別のEngineクラスを用意して、Mainクラス修正のみ
  • →車クラスは修正しなくていい、依存度合いが低い!=疎結合👍👍 
  • 車クラスのテストはエンジンインターフェースを継承したダミークラスを用意してテストできる

クラス図.png

※クラス図の見方

  • 四角の上からクラス名の区域、フィールドの区域、メソッドの区域
    • フィールド:可視性 名前:型 = 初期値
    • メソッド:可視性 名前(引数リスト):返り値
    • 引数リスト:名前:型 をコンマで区切る
  • 可視性記号
表記 意味
+ public:どこからでもアクセス可能
# protected:クラス内および派生したクラスからアクセス可能
- private:クラス内でのみアクセス可能
~ package:パッケージ内でアクセス可能
  • 点線矢印 : 依存関係 (車クラスはホンダのエンジンクラスに依存)
  • 三角矢印の点線: 実装クラスからインターフェースを指す (ホンダエンジンクラスはエンジンインターフェースを継承)
4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1