スプリングアイドルライフサイクルコールバック


空のライフサイクルコールバック?


データベース接続プールやネットワークソケットなどのアプリケーションの開始時に必要な接続を事前に確立し、アプリケーションの終了時にすべての接続を終了するには、オブジェクトの初期化と終了が必要です.スプリングがこの過程をどのように処理しているかを理解しましょう.

スプリングシートのライフサイクル


スプリングシートには、次のライフサイクルがあります.
  • オブジェクトの作成->依存関係の注入
  • スプリングシートはオブジェクトを作成し、依存関係を注入した後に必要なデータを使用する準備をします.したがって、オブジェクトの作成後に依存関係の設定が完了した後に初期化する必要があります.では、開発者はどのようにして依存関係の注入を終了するかを知っていますか?

    初期化の時点を示すスプリング空コールバック方法。


    依存関係注入が完了すると、Springは様々な機能を提供し、SpringBinがいつ初期化されるかをコールバック法で通知することができる.また,初期化時間を教えるように,スプリング容器が終了する前に消滅コールバックを与える.従って、これらの機能により安全に動作することができる.

    スプリングシート内のイベントライフサイクル


    Springbinのイベントには次のライフサイクルがあります.
  • スプリングコンテナの作成
  • スプリング空席の作成
  • 注入依存関係
  • 初期化コールバック::空を生成し、空の依存関係注入を完了した後に
  • を呼び出す
  • 使用
  • 消失前ダイヤル:::空消失前コール
  • スプリングクローズ
  • スプリングアイドルライフサイクルコールバックをサポート


    Springには、空のライフサイクルコールバックをサポートする3つの方法があります.
  • インタフェース::bean、DisposableBeanを初期化
  • 設定情報の初期化方法;指定終了方法
  • @PostConstruct,@Predestory音声サポート
  • 1.インタフェース初期化bean、DisposableBean

    InitializingBeanサポートafterPropertiesSet()メソッドを初期化します.DisposableBeanサポートdestroy()メソッド破棄.

    インタフェースサンプルコードNetworkClient

    package hello.core.lifecycle;
    
    import org.springframework.beans.factory.DisposableBean;
    import org.springframework.beans.factory.InitializingBean;
    
    public class NetworkClient implements InitializingBean, DisposableBean {
    
        private String url;
    
        public NetworkClient() {
            System.out.println("생성자 호출, url = " + url);
            connect();
            call("초기화 연결 메시지");
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public void connect() {
            System.out.println("connect: " + url);
        }
    
        public void call(String message) {
            System.out.println("call: " + url + " message : " + message);
        }
    
        public void disconnect() {
            System.out.println("close: " + url);
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            connect();
            call("초기화 연결 메시지");
        }
    
        @Override
        public void destroy() throws Exception {
            disconnect();
        }
    }

    インタフェースサンプルコードNetworkClientTest

    package hello.core.lifecycle;
    
    import org.junit.jupiter.api.Test;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    class NetworkClientTest {
    
        @Test
        void lifeCycleTest() {
            AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(LifeCycleConfig.class);
            ac.getBean(NetworkClient.class);
            ac.close();
        }
    
        @Configuration
        static class LifeCycleConfig {
            @Bean
            public NetworkClient networkClient() {
                NetworkClient networkClient = new NetworkClient();
                networkClient.setUrl("http://hello-spring.org");
                return networkClient;
            }
        }
    
    }

    インタフェースサンプルコード結果

    생성자 호출, url = null
    connect: null
    call: null message : 초기화 연결 메시지
    NetworkClient.init
    connect: http://hello-spring.org
    call: http://hello-spring.org message : 초기화 연결 메시지
    16:53:52.566 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@446293d, started on Fri May 21 16:53:52 KST 2021
    NetworkClient.close
    close: http://hello-spring.org
    その結果,初期化方法は注入完了後に呼び出され,スプリング容器の終了が呼び出されると破棄方法が呼び出されたと判断できることが分かった.

    初期化によるインタフェースの欠点の解消

  • このインタフェースはスプリング専用インタフェースであるため、コードはスプリング専用インタフェースに依存する.
  • 初期化および破棄方法の名前は変更できません.
  • 修復できない外部ライブラリにコードを適用できません.
  • ちなみに、インタフェースメソッドは現在より良い方法があるので、あまり使われていません.

    2.設定情報を初期化し、終了方法を指定する


    この方法は、@Bean(initMethod = "init", destroyMethod = "close")などの初期化、破棄方法を設定情報に指定することができる.

    情報サンプルコードNetworkClientの設定

    package hello.core.lifecycle;
    
    public class NetworkClient {
    
        private String url;
    
        public NetworkClient() {
            System.out.println("생성자 호출, url = " + url);
            connect();
            call("초기화 연결 메시지");
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public void connect() {
            System.out.println("connect: " + url);
        }
    
        public void call(String message) {
            System.out.println("call: " + url + " message : " + message);
        }
    
        public void disconnect() {
            System.out.println("close: " + url);
        }
    
        public void init() {
            System.out.println("NetworkClient.init");
            connect();
            call("초기화 연결 메시지");
        }
    
        public void close() {
            System.out.println("NetworkClient.close");
            disconnect();
        }
    }

    情報サンプルコードNetworkClientTestの設定

    package hello.core.lifecycle;
    
    import org.junit.jupiter.api.Test;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    class NetworkClientTest {
    
        @Test
        void lifeCycleTest() {
            AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(LifeCycleConfig.class);
            ac.getBean(NetworkClient.class);
            ac.close();
        }
    
        @Configuration
        static class LifeCycleConfig {
    //        @Bean(initMethod = "init", destroyMethod = "close")
            @Bean(initMethod = "init")
            public NetworkClient networkClient() {
                NetworkClient networkClient = new NetworkClient();
                networkClient.setUrl("http://hello-spring.org");
                return networkClient;
            }
        }
    }

    設定情報サンプルコード結果

    생성자 호출, url = null
    connect: null
    call: null message : 초기화 연결 메시지
    NetworkClient.init
    connect: http://hello-spring.org
    call: http://hello-spring.org message : 초기화 연결 메시지
    17:02:02.819 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@3059cbc, started on Fri May 21 17:02:02 KST 2021
    NetworkClient.close
    close: http://hello-spring.org

    設定情報フィーチャーの使用

  • メソッド名を自由に提供
  • SpringBinはSpringコードに依存しない.
  • コードではなく構成情報を使用しているため、コードを修復できない外部ライブラリに初期化および終了方法を適用できます
  • 終了方法の推論

  • @Bean의 destroyMethod属性は特殊な機能を有する
  • ライブラリでは、closeshotdownという名前の終了メソッドが使用されることが多い.
  • @BeanのdestroyMethodデフォルトは推論
  • 推論機能は、closeshotdownの名前のメソッドを自動的に呼び出します.終了メソッドを名前で推定して呼び出します.
  • したがって、スプリング空席に直接登録すると、終了方法がうまく機能します.
  • 3.@PostConstruct,@Predestory宣言


    操作例コードNetwork Client

    package hello.core.lifecycle;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    
    public class NetworkClient {
    
        private String url;
    
        public NetworkClient() {
            System.out.println("생성자 호출, url = " + url);
            connect();
            call("초기화 연결 메시지");
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public void connect() {
            System.out.println("connect: " + url);
        }
    
        public void call(String message) {
            System.out.println("call: " + url + " message : " + message);
        }
    
        public void disconnect() {
            System.out.println("close: " + url);
        }
    
        @PostConstruct
        public void init() {
            System.out.println("NetworkClient.init");
            connect();
            call("초기화 연결 메시지");
        }
    
        @PreDestroy
        public void close() {
            System.out.println("NetworkClient.close");
            disconnect();
        }
    }

    識別サンプルコードNetworkClientTest

    package hello.core.lifecycle;
    
    import org.junit.jupiter.api.Test;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    class NetworkClientTest {
    
        @Test
        void lifeCycleTest() {
            AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(LifeCycleConfig.class);
            ac.getBean(NetworkClient.class);
            ac.close();
        }
    
        @Configuration
        static class LifeCycleConfig {
            @Bean
            public NetworkClient networkClient() {
                NetworkClient networkClient = new NetworkClient();
                networkClient.setUrl("http://hello-spring.org");
                return networkClient;
            }
        }
    
    }

    構文サンプルコードの結果

    생성자 호출, url = null
    connect: null
    call: null message : 초기화 연결 메시지
    NetworkClient.init
    connect: http://hello-spring.org
    call: http://hello-spring.org message : 초기화 연결 메시지
    17:09:03.740 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@3059cbc, started on Fri May 21 17:09:03 KST 2021
    NetworkClient.close
    close: http://hello-spring.org

    技術的特徴

  • これは最新のSpringが推奨する方法です.
  • スプリングではなく他の容器で動作します.
  • 素子スキャンに最適です.
  • 外部ライブラリに適用できないという欠点があります.外部ライブラリを初期化および終了する必要がある場合は、@Bean機能を使用します.
  • リファレンス

  • インフラストラクチャの金英煥スプリングの核心原理-基本編
  • READ


    2021.05.21-最初のコンテンツの作成