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)

我們看到,它會(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)

我們發(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)說明,如果有更好的方式歡迎指正