ApplicationListener的使用方案

ApplicationListener是SpringBoot的監(jiān)聽器,下面是一個(gè)demo
public class ApplicationListenerEnvironmentPrepared implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
    @Override
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
        System.out.println(getClass().getSimpleName());
    }
}

上面用到的事件是ApplicationEnvironmentPreparedEvent,插一句:SpringBoot為ApplicationContextEvent提供了四種事件:

  • ApplicationStartedEvent :spring boot啟動(dòng)開始時(shí)執(zhí)行的事件
  • ApplicationEnvironmentPreparedEvent:spring boot 對(duì)應(yīng)Enviroment已經(jīng)準(zhǔn)備完畢,但此時(shí)上下文context還沒有創(chuàng)建。
  • ApplicationPreparedEvent:spring boot上下文context創(chuàng)建完成,但此時(shí)spring中的bean是沒有完全加載完成的。
  • ApplicationFailedEvent:spring boot啟動(dòng)異常時(shí)執(zhí)行事件

但是,ApplicationListener的功能不止是止步于此,你可以自定義需要攔截的Event,比如我用到了一個(gè)監(jiān)聽事件。

定義好了ApplicationListener下面就是使用了。下面是三種使用的方案

方案一:在啟動(dòng)類中配置

@SpringBootApplication
public class Application {   
     public static void main(String args[]) {      
           SpringApplication app = new SpringApplication(applicationClass);      
           app.addListeners(new StompConnectEvent());        //加入監(jiān)聽事件      
           app.setBannerMode(Banner.Mode.CONSOLE);       
           app.run(args);      
     }   
     protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
           return application.sources(applicationClass);   
     }   

     private static Class<Application> applicationClass = Application.class;
}

方案二:在application.properties中配置(多個(gè)用逗號(hào)隔開)

context.listener.classes=com.StompConnectEvent

上述兩種方案有一個(gè)共同點(diǎn),是什么呢?我們來看下。我在StompConnectEvent中加了一個(gè)構(gòu)造方法,看它會(huì)在什么時(shí)候被啟動(dòng)

AD45D805-D9C5-4D76-A8F5-BD6FA4955E15.png

我們看到,它會(huì)在項(xiàng)目最開始的時(shí)候啟動(dòng)(在banner前我一開始楞是沒找到),這樣在最前面啟動(dòng),會(huì)有什么副作用呢?你試試看在你的Event中使用@Autowired注入一個(gè)bean。為什么要注入?總有業(yè)務(wù)場(chǎng)景需要你在監(jiān)聽事件后做一些事情。注入后你會(huì)發(fā)現(xiàn)報(bào)錯(cuò) java.lang.NullPointerException: null

加上前面的啟動(dòng)時(shí)間和和這個(gè)錯(cuò)誤的類型,我們不難發(fā)現(xiàn),是因?yàn)樵趩?dòng)這個(gè)監(jiān)聽器的時(shí)候,相應(yīng)的BeanFactory還沒加載。換句話說,啟動(dòng)的太早了!

方案三:@Configuration

說了這么多,其實(shí)就是否決了上面兩種啟動(dòng)方案(也不能說否決,只能說使用上面兩種方案,有一些需求達(dá)不到),我的解決方案就是,在定義好ApplicationListener之后,在類前面加上@Configuration,如果不知道@Configuration是啥的自行百度哈~

@Configuration
public class StompConnectEvent implements ……

然后我們?cè)賮砜聪滤裁磿r(shí)候會(huì)被啟動(dòng)

E23365DB-6595-4ECA-80C0-A1E203927A7C.png

我們發(fā)現(xiàn)啟動(dòng)時(shí)間變遲了,然后,驚喜的發(fā)現(xiàn)@Autowired注入不報(bào)錯(cuò)了所有事務(wù)順利解決~

其實(shí)就是對(duì)于啟動(dòng)ApplicationListener的方式做了一些說明,在爬坑的時(shí)候,沒有發(fā)現(xiàn)網(wǎng)上有類似的啟動(dòng)說明,如果有更好的方式歡迎指正

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容