ApplicationListener的使用方案

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

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

  • ApplicationStartedEvent :spring boot啟動開始時執行的事件
  • ApplicationEnvironmentPreparedEvent:spring boot 對應Enviroment已經準備完畢,但此時上下文context還沒有創建。
  • ApplicationPreparedEvent:spring boot上下文context創建完成,但此時spring中的bean是沒有完全加載完成的。
  • ApplicationFailedEvent:spring boot啟動異常時執行事件

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

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

方案一:在啟動類中配置

@SpringBootApplication
public class Application {   
     public static void main(String args[]) {      
           SpringApplication app = new SpringApplication(applicationClass);      
           app.addListeners(new StompConnectEvent());        //加入監聽事件      
           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中配置(多個用逗號隔開)

context.listener.classes=com.StompConnectEvent

上述兩種方案有一個共同點,是什么呢?我們來看下。我在StompConnectEvent中加了一個構造方法,看它會在什么時候被啟動

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

我們看到,它會在項目最開始的時候啟動(在banner前我一開始楞是沒找到),這樣在最前面啟動,會有什么副作用呢?你試試看在你的Event中使用@Autowired注入一個bean。為什么要注入?總有業務場景需要你在監聽事件后做一些事情。注入后你會發現報錯 java.lang.NullPointerException: null

加上前面的啟動時間和和這個錯誤的類型,我們不難發現,是因為在啟動這個監聽器的時候,相應的BeanFactory還沒加載。換句話說,啟動的太早了!

方案三:@Configuration

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

@Configuration
public class StompConnectEvent implements ……

然后我們再來看下它什么時候會被啟動

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

我們發現啟動時間變遲了,然后,驚喜的發現@Autowired注入不報錯了所有事務順利解決~

其實就是對于啟動ApplicationListener的方式做了一些說明,在爬坑的時候,沒有發現網上有類似的啟動說明,如果有更好的方式歡迎指正

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容