下面咱們來介紹,使用spring的@Async註解使Even監聽事件,變爲異步事件,這只是很簡單的應用,若是要配合業務使用,請根據自身業務來調整
本人環境是:JDK版本號1.8,spring版本爲4.2web
首先,咱們先來看看,不使用@Async註解的基礎事件,是怎麼寫的spring
1.咱們先定義一個事件,該類繼承 ApplicationEven的抽象類tomcat
public class DemoEvent extends ApplicationEvent{ //事件監聽消息 private String msg; public DemoEvent(Object source,String msg) { super(source); this.msg=msg; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; }
2.事件有了,那麼咱們就確定須要一個發佈者吧,否則,誰知道你須要發佈任務呢.app
@Component public class DemoPubLisher { @Autowired private ApplicationContext applicationContext; //事件發佈方法 public void pushListener(String msg){ applicationContext.publishEvent(new DemoEvent(this,msg)); } }
3.既然發佈者有了,確定也要有一個監聽者嘛,時刻監聽者發佈者是否有發佈任務,而後進行處理異步
@Component public class DemoEventListener implements ApplicationListener<DemoEvent>{ static Logger log = Logger.getLogger(DemoEventListener.class); //監聽事件執行方法 public void onApplicationEvent(DemoEvent event) { String msg = event.getMsg(); log.info("DemoEventListener,監聽到了 DemoEvent 發佈的消息:"+msg); //讓線程睡眠是用來測試,監聽者監聽到發佈者發佈事件後,執行任務的時候 //是不是同步執行 if(msg.equals("測試消息監聽")){ try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
監聽者跟發佈者@Component 註解相信你們必定不陌生了,可是怕有些同窗不知道,仍是解釋下,這表示將該類註冊爲一個spring容器中的一個bean!測試
事件,監聽者,發佈者都有了,那麼咱們就來進行測試,看看事件之間的執行,是同步的,仍是異步的.this
下面就是測試代碼spa
@Configuration @ComponentScan("com.spring.annotation.event") public class EventConfig { public static void main(String[] args){ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EventConfig.class); //用注入的形式完成事件發佈 DemoPubLisher pushListener = context.getBean(DemoPubLisher.class); pushListener.pushListener("測試消息監聽"); pushListener.pushListener("測試消息監聽1"); context.close(); } }
@Configuration 註解表示,這是一個組合註解,表示這是一個配置文件,也是一個bean,由於裏面包含了@Component註解線程
@ComponentScan("com.spring.annotation.event") 掃描包,將包含spring註解的類,註冊爲一個bean日誌
下面,咱們執行main方法,測試看打印結果
紅色區域就是打印結果,箭頭是打印時間,能夠發現,這是同步執行的,只有等第一個事件執行完畢後,纔會執行第二個,若是想要事件監聽者,異步執行怎麼辦?咱們可使用@Async 註解,改2個地方就行了,下面是代碼
咱們先修改監聽者.
@Component public class DemoEventListener implements ApplicationListener<DemoEvent>{ static Logger log = Logger.getLogger(DemoEventListener.class); //監聽事件執行方法 @Async public void onApplicationEvent(DemoEvent event) { String msg = event.getMsg(); log.info("DemoEventListener,監聽到了 DemoEvent 發佈的消息:"+msg); //讓線程睡眠是用來測試,監聽者監聽到發佈者發佈事件後,執行任務的時候 //是不是同步執行 if(msg.equals("測試消息監聽")){ try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
在方法上,增長了@Async註解,表示這是一個異步方法,若是註解使用到類上,表示類下全部方法,都是異步的.
接下來,咱們在修改EvenConfig類
@Configuration @ComponentScan("com.spring.annotation.event") @EnableAsync public class EventConfig { public static void main(String[] args){ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EventConfig.class); //用注入的形式完成事件發佈 DemoPubLisher pushListener = context.getBean(DemoPubLisher.class); pushListener.pushListener("測試消息監聽"); pushListener.pushListener("測試消息監聽1"); context.close(); } }
在類上,咱們增長了註解@EnableAsync 表示開啓異步@Async註解,不使用@EnableAsync註解,@Async是不會生效的.
執行方法,來看看打印結果吧
咱們能夠發現,打印時間是一致的,表示第一個監聽執行睡眠,並不會影響第二個的執行,咱們能夠從日誌看出一二,在打印結果的時間後面 有個 SimpleAsyncTaskExecutor-1,跟SimpleAsyncTaskExecutor-2 分別是兩個線程,說明,監聽者,每次執行該方法,都是新起一個線程去執行,因此監聽到的第二個,並不會等第一個執行完畢在執行第二個.
有同窗會問了,若是是啓動tomcat怎麼辦,@EnableAsync註解應該加到哪裏呢?
若是是普通的web項目,那麼@EnableAsync註解,你添加到監聽者類上邊就能夠了,表示開啓異步註解
以上,@Async跟@EnableAsync註解都是分別是Spring3.0跟3.1版本纔有,若是高於此版本,就不須要擔憂沒有該註解,若是想知道@EnableAsync註解的原理,能夠查看 AsyncConfigurationSelector 類的源碼,上面有解釋,這裏,就不給你們進行解釋了
以上,均爲本人測試而得出的結果,可能會有出入,或者錯誤,歡迎指正
歡迎轉載,請註明出處跟做者,謝謝!