Spring中使用@Async註解使Even監聽事件之間的執行變爲異步

下面咱們來介紹,使用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 類的源碼,上面有解釋,這裏,就不給你們進行解釋了

 

 

以上,均爲本人測試而得出的結果,可能會有出入,或者錯誤,歡迎指正

 

歡迎轉載,請註明出處跟做者,謝謝!

相關文章
相關標籤/搜索