0 概述
ContextRefreshedEvent 事件會在Spring容器初始化完成會觸發該事件。我們在實際工作也可以能會監聽該事件去做一些事情,但是有時候使用不當也會帶來一些問題。
1 防止重復觸發
主要因為對於web應用會出現父子容器,這樣就會觸發兩次,那么如何避免呢?下面給出一種簡單的解決方案。
@Component public class TestTask implements ApplicationListener<ContextRefreshedEvent> { private volatile AtomicBoolean isInit=new AtomicBoolean(false); @Override public void onApplicationEvent(ContextRefreshedEvent event) { //防止重復觸發 if(!isInit.compareAndSet(false,true)) { return; } start(); } private void start() { //開啟任務 System.out.println("****-------------------init---------------******"); } }
2 監聽事件順序問題
Spring 提供了一個SmartApplicationListener類,可以支持listener之間的觸發順序,普通的ApplicationListener優先級最低(最后觸發)。
@Component public class LastTask implements SmartApplicationListener { private volatile AtomicBoolean isInit = new AtomicBoolean(false); @Override public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) { return eventType == ContextRefreshedEvent.class; } @Override public boolean supportsSourceType(Class<?> sourceType) { return true; } @Override public void onApplicationEvent(ApplicationEvent event) { if (!isInit.compareAndSet(false, true)) { return; } start(); } private void start() { //開啟任務 System.out.println("LastTask-------------------init------------ "); } //值越小,就先觸發 @Override public int getOrder() { return 2; } }