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中加了一個構造方法,看它會在什么時候被啟動
我們看到,它會在項目最開始的時候啟動(在banner前我一開始楞是沒找到),這樣在最前面啟動,會有什么副作用呢?你試試看在你的Event中使用@Autowired注入一個bean。為什么要注入?總有業務場景需要你在監聽事件后做一些事情。注入后你會發現報錯 java.lang.NullPointerException: null
加上前面的啟動時間和和這個錯誤的類型,我們不難發現,是因為在啟動這個監聽器的時候,相應的BeanFactory還沒加載。換句話說,啟動的太早了!
方案三:@Configuration
說了這么多,其實就是否決了上面兩種啟動方案(也不能說否決,只能說使用上面兩種方案,有一些需求達不到),我的解決方案就是,在定義好ApplicationListener之后,在類前面加上@Configuration,如果不知道@Configuration是啥的自行百度哈~
@Configuration
public class StompConnectEvent implements ……
然后我們再來看下它什么時候會被啟動
我們發現啟動時間變遲了,然后,驚喜的發現@Autowired注入不報錯了所有事務順利解決~
其實就是對于啟動ApplicationListener的方式做了一些說明,在爬坑的時候,沒有發現網上有類似的啟動說明,如果有更好的方式歡迎指正