1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Spring Boot 中初始化資源的方式,你知道幾種?

        共 7009字,需瀏覽 15分鐘

         ·

        2021-05-24 16:25

        程序員的成長之路
        互聯(lián)網(wǎng)/程序員/技術(shù)/資料共享 
        關(guān)注


        閱讀本文大概需要 3.5 分鐘。

        作者:小破孩樓主

        來源:cnblogs.com/zouhong/p/14415713.html

        假設(shè)有這么一個需求,要求在項目啟動過程中,完成線程池的初始化,加密證書加載等功能,你會怎么做?如果沒想好答案,請接著往下看。今天介紹幾種在Spring Boot中進(jìn)行資源初始化的方式,幫助大家解決和回答這個問題。

        CommandLineRunner

        • 定義初始化類 MyCommandLineRunner
        • 實現(xiàn) CommandLineRunner 接口,并實現(xiàn)它的 run() 方法,在該方法中編寫初始化邏輯
        • 注冊成Bean,添加 @Component注解即可
        • 示例代碼如下:

        package cn.zh.controller;

        import org.springframework.boot.CommandLineRunner;
        import org.springframework.core.annotation.Order;
        import org.springframework.stereotype.Component;

        @Componentpublic class MyCommandLineRunner implements CommandLineRunner {
           
            @Override
            public void run(String... args) throws Exception {
                System.out.println("項目初始化---------------11");
            }
        }

        實現(xiàn)了 CommandLineRunner 接口的 Component 會在所有 Spring Beans 初始化完成之后, 在 SpringApplication.run() 執(zhí)行之前完成。下面通過加兩行打印來驗證我們的測試。

        package cn.zh;

        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;

        @SpringBootApplication
        public class ProcApplication {

            public static void main(String[] args) {
                System.out.println("...start SpringApplication.run");
                SpringApplication.run(ProcApplication.class,args);
                System.out.println("....end SpringApplication.run");
            }
        }

        ApplicationRunner

        • 定義初始化類 MyApplicationRunner
        • 實現(xiàn) ApplicationRunner 接口,并實現(xiàn)它的 run() 方法,在該方法中編寫初始化邏輯
        • 注冊成Bean,添加 @Component注解即可
        • 示例代碼如下:

        package cn.zh.controller;

        import org.springframework.boot.ApplicationArguments;
        import org.springframework.boot.ApplicationRunner;
        import org.springframework.core.annotation.Order;
        import org.springframework.stereotype.Component;

        import javax.annotation.PostConstruct;

        @Component
        public class MyApplicationRunner implements ApplicationRunner {
            @Override
            public void run(ApplicationArguments args) throws Exception {
                System.out.println("項目初始化二---------");
            }

           
        }

        可以看到,通過實現(xiàn) ApplicationRunner 接口,和通過實現(xiàn) CommandLineRunner 接口都可以完成項目的初始化操作,實現(xiàn)相同的效果。兩者之間唯一的區(qū)別是 run() 方法中自帶的形參不相同,在 CommandLineRunner 中只是簡單的String... args形參,而 ApplicationRunner 則是包含了 ApplicationArguments 對象,可以幫助獲得更豐富的項目信息。

        @Order

        如果項目中既有實現(xiàn)了 ApplicationRunner 接口的初始化類,又有實現(xiàn)了 CommandLineRunner 接口的初始化類,那么會是哪一個先執(zhí)行呢?測試告訴我們,答案是實現(xiàn)了 ApplicationRunner 接口的初始化類先執(zhí)行,我想這點倒是不需要大家過分去關(guān)注為什么。但如果需要改變兩個初始化類之間的默認(rèn)執(zhí)行順序,那么使用 @Order 注解就可以幫助我們解決這個問題。

        @Component
        @Order(1)
        public class MyCommandLineRunner implements CommandLineRunner {
            /**
             * Callback used to run the bean.
             *
             * @param args incoming main method arguments
             * @throws Exception on error
             */
            @Override
            public void run(String... args) throws Exception {
                System.out.println("項目初始化---------------11");
            }
        }
        @Component
        @Order(2)
        public class MyApplicationRunner implements ApplicationRunner {
            @Override
            public void run(ApplicationArguments args) throws Exception {
                System.out.println("項目初始化二---------");
            }

            @PostConstruct
            public void init(){
                System.out.println("@PostConstruct初始化");
            }
        }

        @PostConstruct

        使用 @PostConstruct 注解同樣可以幫助我們完成資源的初始化操作,前提是這些初始化操作不需要依賴于其它Spring beans的初始化工作。
        可以看到 @PostConstruct 注解是用在方法上的,寫一個方法測試一下吧。

        @PostConstruct
            public void init(){
                System.out.println("@PostConstruct初始化");
            }

        • 注意:


          • 只有一個非靜態(tài)方法能使用此注解
          • 被注解的方法不得有任何參數(shù)
          • 被注解的方法返回值必須為void
          • 被注解方法不得拋出已檢查異常
          • 此方法只會被執(zhí)行一次
        • 綜上,使用 @PostConstruct 注解進(jìn)行初始化操作的順序是最快的,前提是這些操作不能依賴于其它Bean的初始化完成。通過添加 @Order 注解,我們可以改變同層級之間不同Bean的加載順序。

        InitializingBean

        InitializingBean 是 Spring 提供的一個接口,只包含一個方法 afterPropertiesSet()。凡是實現(xiàn)了該接口的類,當(dāng)其對應(yīng)的 Bean 交由 Spring 管理后,當(dāng)其必要的屬性全部設(shè)置完成后,Spring 會調(diào)用該 Bean 的 afterPropertiesSet()。

        @Component
        public class MyListener1 implements InitializingBean {
            @Autowired
            private ShopInfoMapper shopInfoMapper;
            @Override
            public void afterPropertiesSet() {
                //使用spring容器中的bean
                //System.out.println(shopInfoMapper.selectById("1").getShopName());
                System.out.println("項目啟動OK");
            }
        }

        ApplicationListener

        ApplicationListener 就是spring的監(jiān)聽器,能夠用來監(jiān)聽事件,典型的觀察者模式。如果容器中有一個ApplicationListener Bean,每當(dāng)ApplicationContext發(fā)布ApplicationEvent時,ApplicationListener Bean將自動被觸發(fā)。這種事件機制都必須需要程序顯示的觸發(fā)。
        其中spring有一些內(nèi)置的事件,當(dāng)完成某種操作時會發(fā)出某些事件動作。比如監(jiān)聽ContextRefreshedEvent事件,當(dāng)所有的bean都初始化完成并被成功裝載后會觸發(fā)該事件,實現(xiàn)ApplicationListener接口可以收到監(jiān)聽動作,然后可以寫自己的邏輯。
        同樣事件可以自定義、監(jiān)聽也可以自定義,完全根據(jù)自己的業(yè)務(wù)邏輯來處理。所以也能做到資源的初始化加載。

        @Component
        public class MyListener1 implements ApplicationListener {
            @Override
            public void onApplicationEvent(ApplicationEvent applicationEvent) {
                
                //打印出每次事件的名稱
                System.out.println(applicationEvent.toString());
                
                if (applicationEvent instanceof ApplicationReadyEvent) {
                    System.out.println("項目啟動OK");
                }
            }
        }


        <END>

        推薦閱讀:

        為什么下載小電影時,經(jīng)常會卡在99%?

        如何打日志才能方便排查問題?

        最近面試BAT,整理一份面試資料《Java面試BATJ通關(guān)手冊》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫、數(shù)據(jù)結(jié)構(gòu)等等。

        獲取方式:點個「在看」,點擊上方小卡片,進(jìn)入公眾號后回復(fù)「面試題」領(lǐng)取,更多內(nèi)容陸續(xù)奉上。

        朕已閱 

        瀏覽 39
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            日笔视频 | 欧美视频在线第3页导航 | se欧美 | 韩国一区电影 | 精品视频一区二区三区 | 调教师sm扩张器带乳夹 | 美女被操爽了视频 | 91在线无码精品秘 入口竹美 | 女同啪啪免费网站www | 国产一级婬片永久免费看久久 |