Spring(2)-IoCについて


Prolog


DIとIoCを整理するために、DIの整理量が多くなりました.スクロールの圧力がかかる可能性もあるとみられ、今後、大量のコンテンツを一度に閲覧するのは容易ではないと考え、DIとIOCを単独で整理することにした.
こんなに長くてもいいですか?!重要だが、筆者は分からない概念を理解する際に多くの議論を展開し、少なくとも3回は精読する.この文章も繰り返し読むとその概念を吸収できるという考えで書かれています.

IoC(Inversion of Control)-制御反転


今Java登场..。


Javaベースのアプリケーションの開発を開始する最初の段階では,開発者はJavaオブジェクトの作成,接続オブジェクト間の依存関係などの制御権を持つ.
また、過去には多くの形式のオープンソースがあり、共通の焦点は異なるオブジェクトをどのように接続するかです.
Servlet,EJBの出現に伴い,開発者が持つ制御権と管理対象ライフサイクルの権限はサーブレットとEJBを管理するコンテナに移行した.
これは、オブジェクトの生成からライフサイクルの管理まで、すべてのオブジェクトの制御権が変化したことを意味し、これが制御権の逆転、すなわちIocの概念である.

スプリング角度からIoCを定義する🍃


オブジェクトのライフサイクル(作成-設定-初期化-消滅)から開始します.ライフサイクルの管理は、開発者ではなくスプリングフレームワークによって行われます.つまり、すべてのオブジェクトの制御権が変更され、マスターになります.
すなわち、制御反転(IoC)は、開発者ではなく開発者によって方法またはオブジェクトの呼び出しが決定されることを意味し、制御フローを減少させることによって変化させるものとみなすことができる.
あなたたちがやったことは全部やってあげますから、これを使ってください.

IoCを使うメリットは何ですか?


オブジェクト向けプログラミングという言葉を振り返ってみましょう.
オブジェクト向けプログラミングは、各オブジェクトが自分の役割と責任を十分に発揮し、互いに協力し、変更を柔軟にプログラミングできるプログラミングテクニックです.これは、高集約および低結合を実現するために、各オブジェクトを正確にカプセル化することを意味する.
この観点から、制御の反転はサードパーティ(すなわち、ロールと責任を他のオブジェクト/コンテナに委任する)をもたらします.あとは気にしなくてもいいです.
これにより、柔軟なコード構造を変更に導入し、企業内の多くのオブジェクトを容易に管理できます.
オブジェクトの作成、オブジェクトの消去など、私が作成するコードに管理コードが含まれており、ビジネスコードも含まれている場合は?むしろもっと
機能(コード)は随時変更できます.
次に例を示します.
Aという名前のオブジェクトを作成していて、AオブジェクトがBオブジェクトを修正して追加する必要がある場合はどうなりますか?
これだけビジネスが完了している場合は関係ありませんが、1000の場所でAというオブジェクトを再使用すると、これは困難なタスクになります.
つまり,객체를 관리해주는 독립적인 존재(マクロ的にはコンテナ,ミクロ的にはデザインモード)と그 외 본인이 구현하고자 하는 부분は,注目点を分離し,それぞれの役割で変更コードを柔軟に記述できる構造であるため,制御への逆転といえる.
まとめて、IoCを適用すると
オブジェクトの依存性を逆転させることで、オブジェクト間の結合(分散結合)を低減し、柔軟なコードを記述することができ、可読性とコードの重複とメンテナンスを簡素化できます.

IoCの実装方法


IoCを実施する方法はDLおよびDIを含む.

  • DLとは?


    「依存関係検索」(Dependency Lookup)とは、依存関係を外部から入力するのではなく、依存関係が必要なオブジェクトから直接検索することを意味します.

  • DIとは何ですか。


    DIはSpringでサポートされているIoCの形式で、各レイヤ間、各クラス間に必要な依存関係がある場合、コンテナは自動的に接続され、各クラス間の依存関係はbean設定情報に基づいてコンテナが自動的に接続されるという概念と見なすことができます.
    DIの詳細についてはSpring(1)-DIについてでまとめた.
  • IoCとDIの違い


    IOCは、オブジェクトの流れやライフサイクル管理など、独立したサードパーティに役割と責任を任せる設計モデルです.
    IoCの概念はスプリングに限定されるものではない.
    しかし,DIはインタフェースを介してオブジェクトを動的に注入して柔軟なプログラミングを実現するモードであり,IoCより注入依存性を重視している.

    IoC例


    一般依存関係

  • Barista
  • class Barista {
    	private ArabicaBean arabicaBean;
        
        public Barista() {
        	this.arabicaBean = new ArabicaBean();
        }
        
        public void roasting() {
        	System.out.println("나는! 나는! 나는! 원두를 볶는다!");
     		this.arabicaBean.roastBeans();
        }
    }
  • ArabicaBean, RobustaBean
  • class ArabicaBean {
    	public void roastBeans() {
        	System.out.println("아라비카 원두를 볶는다!");
        }
    }
    
    class RobustaBean {
    	public void roastBeans() {
        	System.out.println("로부스타 원두를 볶는다!");
        }
    }
  • Cafe
  • public class Cafe {
    	public static void main(String[] args) {
    		Barista barista = new Barista();
    		barista.roasting();
    	}
    }
    上記のコードでは、Bastaはベイク処理()を実行するためにArabicabeanを必要とし、Bastaは自分でArabicabeanを作成して使用します.この状態は、BastaがArabicaBeanに依存していることを示します.
    コーヒーメーカーが異なる品種の大豆を使う必要がある場合は、Baristaの多くの部分を修正する必要があります.

    では、この依存関係を逆転させましょう。

  • CoffeeBean
  • interface CoffeeBean {
    	void roastBeans();
    }
    
    class ArabicaBean implements CoffeeBean {
    	public void roastBeans() {
        	System.out.println("아라비카 원두를 볶는다!");
        }
    }
    
    class RobustaBean implements CoffeeBean {
    	public void roastBeans() {
        	System.out.println("로부스타 원두를 볶는다!");
        }
    }
  • Barista
  • class Barista {
    	private CoffeeBean coffeeBean;
        
        public void setCoffeeBean(CoffeeBean coffeeBean) {
    		this.coffeeBean = coffeeBean;
    	}
        
        public void roasting() {
        	System.out.println("나는! 나는! 나는! 원두를 볶는다!");
            this.coffeeBean.roastBeans();
        }
    }
  • Cafe
  • public class Cafe {
    	public static void main(String[] args) {
        	Barista barista = new Barista();
            
            // ArabicaBean
            CoffeeBean arabicaBean = new ArabicaBean();
            barista.setCoffeeBean(arabicaBean);
            barista.roasting();
            
            // RobustaBean
            CoffeeBean robustaBean = new RobustaBean();
            barista.setCoffeeBean(robustaBean);
            barista.roasting();
        }
    }
    今回,インタフェースCoffeeBeanを作成し,各実装(実装)CoffeeBeanのクラスを作成した.コーヒーメーカーは、自分で作ってコーヒー豆を使うのではなく、外部からコーヒー豆を作ってコーヒー豆を使う.また、タイプをインタフェースに変更するため、コードを変更せずに任意の丸いヘッドを使用できます.
    コーヒーメーカーがコーヒー豆に依存する関係が変わった.この現象を依存反転の原則(DIP)と呼ぶ.
    ただし、コードの実行部分でCoffeeBeanのタイプを選択して、Bastaに直接作成して設定する必要があります.

    では、スプリングにIoC/DIコンセプトが適用されたらどうなるのでしょうか。


    ここからSpringプログラムです.
  • CoffeeBean
  • interface CoffeeBean {
    	String roastBeans();
    }
    
    @Component("arabicaBean") // arabicaBean이란 이름을 가진 Bean(얘는 원두가 아닌 객체입니다)으로 등록
    public class ArabicaBean implements CoffeeBean {
    	public String roastBeans() {
        	return "아라비카 원두를 볶는다!";
        }
    }
    
    @Component("robustaBean") // robustaBean이란 이름을 가진 Bean으로 등록
    public class RobustaBean implements CoffeeBean {
    	public String roastBeans() {
        	return "로부스타 원두를 볶는다!";
    	}
    }
  • Barista
  • @Component	// 의존성을 주입받는 객체도 Bean으로 등록되어있어야 합니다.
    public class Barista {
    	
        @Autowired	// 의존성 주입
        @Qualifier("arabicaBean")	// 사용할 의존 객체를 선택할 수 있도록 해줍니다
    	private CoffeeBean coffeeBean;
        
        public String roasting() {
        	return "나는! 나는! 나는! 원두를 볶는다! " + this.coffeeBean.roastBeans();
        }
  • RoastController
  • @RestController
    public class RoastController {
    	
    	@Autowired	// Barista라는 타입을 가진 Bean을 찾아서 주입시킴
        private Barista barista;
        
        @RequestMapping("/roast")
        public String roastDriver() {
        	return barista.roasting();
        }
    }
    さっきmain()でカフェさんがコーヒー豆をセットして使いました.ただし、SpringのIoc/DIの例では、CoffeeBeanオブジェクトはどこにも作成されていません.
    このコードでは、肉眼ではわかりにくいですが、コメント@Component付きの変数のタイプが表示され(同じタイプのbeanが複数ある場合は名前を参照)、オブジェクトが変数に注入されます.

    サマリ



    スプリング内のコンテンツは、オブジェクトを作成し、自動的にオブジェクトに注入します.このようにして作成されたオブジェクトは、自分がどこで使用されるか分かりません.これが制御の逆転原則であり,スプリングは依存注入(DI)の概念をスプリングとしてオーダーメイドする.

    Epilogue


    DIと一緒に10日間でIocをまとめました
    この曲は最短ルートで行けるのですが、やはり回り道をしなくてはいけないという感じでしたが、二人の目的地は同じで、この緩やかな方向でも学べるものなので、悔いは残らないと思います.
    去年は何も知らずにプロジェクトをした時だけ後悔します.その時、スプリングの基本概念も熟知せず、プロジェクトに投入され、シャベルは完成したが、満足のいく結果はなかった.
    しかし今では様々な形でこれだけ早く知っておくべき基本概念を学び、なぜ以前にやったプロジェクトでbeanに関するエラー(Null PointerExceptionなど)が発生したのかを知ることができます.
    今後のプロジェクトに適用して、より拡張性と変更に役立つコードを書く自信があります.

    References


  • スプリングフレーム2-コンテナと制御反転(IoC)

  • Spring DIとIoC

  • IoCとDIは何ですか

  • [トビーのスプリング1枚]対象との依存関係-1

  • 制御反転(IoC)と依存注入(DI)とは?

  • SPRING-オブジェクトとの依存関係(4)

  • [Sping]Ioc容器−依存ロックと依存注入

  • IOC / DL / DI

  • 反転スプリング制御,注入依存性(DI)

  • [スプリング]Spring IoC/DI/DLコンセプト

  • IoC/DI&Spring beanライフサイクル例
  • 紛らわしいことや間違いがあれば,ご指摘ください🙇‍♂️