Spring IoC容器


1. Inversion of Control


  • 一般的な制御フローは、各オブジェクトに制御権があり、オブジェクトが使用するオブジェクトを自分で選択し、自分で生成します.

  • フレームでは、制御はフレームにあります.これは、開発者が作成したアプリケーションコードが、ロードおよび使用するライブラリだけでなく、フレームワークで使用されるためです.このような従来の制御の流れとは反対にIoC
  • 2.IoC容器


    オブジェクトの作成、破壊、結合、およびオブジェクト間の依存関係を確立するオブジェクト.

  • どのクラスを使用するかを登録し、必要な依存関係を確立し、ライフサイクルを管理してインスタンスを返す

  • IoCコンテナオブジェクトをクライアントとして,これらのオブジェクトは依存性を注入できるため結合度が緩やかになる.

  • SpringでApplicationContextインタフェースで提供

  • 3. ApplicationContext


    スプリング上のIoC容器

  • ApplicationContextが管理するオブジェクトをbeanと呼びます

  • ApplicationContextは、コンフィギュレーションMetadataから実際に作成する必要があるbean情報を取得します.Java(n o n t i o t i o n C o n f i g ApplicationContext)またはXML(GenericXmlApplicationContext)を使用して作成できます.
  • 3-1. デフォルトではApplicationContextを使用しています

    // AppConfiguration.java
    
    @Configuration  // 스프링의 애노테이션으로 ApplicationContext의 설정 메타데이터로 인식되게 한다 
    public class AppConfiguration {
    
        @Bean  // 아래 메소드는 Bean을 정의한 Configuration Metadata가 된다 
        public ExampleBean exampleBean() {
            return new ExampleBean();
        }
        
    }
    
    // 설정파일로 어플리케이션 컨택스트 생성 
    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfiguration.class);
    // Bean 생성 
    ExampleBean exBean = applicationContext.getBean(ExampleBean.class);
  • ClassName.class :
  • 3-2. パラメータを使用してbeanを接続する

  • 構成中のメソッドを呼び出してbean間の依存性を設定することもでき、以下に示す
  • @Configuration 
    public class AppConfiguration {
    
        @Bean  
        public ExampleBean exampleBean() {
            return new ExampleBean();
        }
        
        @Bean
        public AnotherBean antoherBean() {
            return new AnotherBean(exampleBean());
        }
        
    }
  • より美しいパラメータを注入することもできます.スプリングは自己処理
  • @Configuration 
    public class AppConfiguration {
    
        @Bean  
        public ExampleBean exampleBean() {
            return new ExampleBean();
        }
        
        @Bean
        public AnotherBean antoherBean(ExampleBean exampleBean) {
            return new AnotherBean(exampleBean);
        }
        
    }
  • springはジェネレータベースDIを推奨する.これは、nullメンバーがいつでも存在しないことを保証し、finalキーワードでメンバー変数を一定に保つことができるためです
  • 3-3. Benループ依存問題

  • 他のループ依存問題と同様にbean間のループ依存はデッドロック
  • をもたらす
    // ObjectA는 ObjectB의 인스턴스의 생성을 기다리고 ObjectB는 ObjectA의 인스턴스 생성을 기다린다
    
    @Configuration 
    public class AppConfiguration {
    
        @Bean
        public ObjectA objectA(ObjectB objectB) {
            return new ObjectA(objectB);
        }
        
        @Bean
        public ObjectB objectB(ObjectA objectA) {
            return new ObjectB(objectA);
        }
    
    }

    4.beanライフサイクルコールバック


    上記のプロファイルからApplicationContextを生成し、close()で破棄できます.
    applicationContext.close();

  • アプリケーションコンテキストが破棄されると、登録されたbeanも破棄されます.
  • close()でアプリケーションコンテキストを破棄しない限り、bean破棄コールバックは呼び出されません.

  • コールバック関数:他のコードの引数として渡される実行可能コード.コールバックを受信するコードは、必要に応じて直ちにコールバックを実行するか、後で実行することができます.
  • 4-1. コールバックの生成:作成後のアクション

  • @PostConstructメソッド呼び出し(ある場合)
  • BeanInitializingBeanインタフェースの実装時にafterPropertiesSet呼び出し
  • @BeanプレゼンテーションのinitMethodに設定されたメソッド呼び出し
  • @Component
    public class SomeComponent implements InitializingBean {
        // @PostConstruct 적용 메소드
        @PostConstruct
        public void postConstruct() {
            System.out.println("postConstruct 호출");
        }
    
        // InitializingBean 구현 메소드
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("afterPropertiesSet 호출");
        }
    }
    
    
    ...다른파일...
    
    
    @Configuration
    public class Config {
        // initMethod 설정 메소드
        @Bean(initMethod = "init")
        public Component component() {
            ...
        }
    }
    
    class Component {
        public void init() {
            ...
        }
    }

    4-2. 消滅コールバック:消滅後の作業

  • @PreDestroyメソッド呼び出し(ある場合)
  • BeanDisposableBeanインタフェースの実装時にdestroy
  • を呼び出す
  • @BeanプレゼンテーションのdestroyMethodに設定されたメソッド呼び出し
  • @Component
    public class SomeComponent implements DisposableBean {
        @PreDestroy
        public void preDestroy() {
            System.out.println("preDestroy 호출");
        }
    
        @Override
        public void destroy() throws Exception {
            System.out.println("destroy 호출");
        }
    }
    
    ...다른파일...
    
    
    @Configuration
    public class Config {
        // destroyMethod 설정 메소드
        @Bean(destroyMethod = "destroyMethod")
        public Component component() {
            ...
        }
    }
    
    class Component {
        public void destroyMethod() {
            ...
        }
    }