欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解SpringBoot實現(xiàn)事件同步與異步監(jiān)聽

 更新時間:2022年06月22日 09:25:35   作者:IT利刃出鞘  
這篇文章主要通過示例為大家詳細(xì)介紹了SpringBoot中的事件的用法和原理以及如何實現(xiàn)事件同步與異步監(jiān)聽,快跟隨小編一起學(xué)習(xí)學(xué)習(xí)吧

簡介

說明

本文用示例介紹SpringBoot中的事件的用法及原理。

事件監(jiān)聽簡述

事件的發(fā)布與監(jiān)聽從屬于觀察者模式;和MQ相比,事件的發(fā)布與監(jiān)聽偏向于處理服務(wù)內(nèi)的某些邏輯。 

多個監(jiān)聽器可以監(jiān)聽同一個事件。例如:發(fā)布了事件A,監(jiān)聽器A和監(jiān)聽器B都監(jiān)聽了事件A,則監(jiān)聽器A和B都會進行處理。

同步與異步監(jiān)聽

監(jiān)聽方式特點使用時機
同步監(jiān)聽發(fā)布器線程與監(jiān)聽器線程處于同一線程1.監(jiān)聽邏輯處理較快
2.需要緊接著根據(jù)監(jiān)聽器追蹤業(yè)務(wù)線程
異步監(jiān)聽發(fā)布器線程與監(jiān)聽器線程處于不同線程1.監(jiān)聽邏輯處理比較耗時
2.追求響應(yīng)性能

事件的順序

可使用實現(xiàn)Ordered接口的方式,調(diào)整監(jiān)聽器順序。

注意:必須是同時實現(xiàn) ApplicationListener<MyEvent>,Ordered這樣的方法才能控制順序。

下邊幾種都是無法控制順序的:

  • @Component+@EventListerner+實現(xiàn)Ordered
  • 實現(xiàn) ApplicationListener<MyEvent>+@Order

實例

同步監(jiān)聽(無序)

事件

package com.example.event;
 
import org.springframework.context.ApplicationEvent;
 
public class MyEvent extends ApplicationEvent {
 
    public MyEvent(Object source) {
        super(source);
    }
 
}

監(jiān)聽器

監(jiān)聽器1

package com.example.event;
 
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
 
@Component
public class MyListener {
    @EventListener
    public void abc(MyEvent event) {
        System.out.println("監(jiān)聽器:        " + "MyListener");
        System.out.println("監(jiān)聽器所在線程:" + Thread.currentThread().getName());
        System.out.println("事件:          " + event);
        System.out.println("事件的數(shù)據(jù):    " + event.getSource());
    }
}

監(jiān)聽器2

package com.example.event;
 
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
 
@Component
public class MyListener2 {
 
    @EventListener
    public void onApplicationEvent(MyEvent event) {
        System.out.println("監(jiān)聽器:      " + "MyListener2");
        System.out.println("  所在線程:  " + Thread.currentThread().getName());
        System.out.println("  事件:      " + event);
        System.out.println("  事件的數(shù)據(jù):" + event.getSource());
    }
}

發(fā)布器

package com.example.event;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
 
@Component
public class MyPublisher {
    @Autowired
    ApplicationContext applicationContext;
 
    public void myPublish(String message) {
        System.out.println("發(fā)布器所在線程:" + Thread.currentThread().getName());
        applicationContext.publishEvent(new MyEvent(message));
    }
}

測試

寫一個Controller

package com.example.controller;
 
import com.example.event.MyPublisher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class HelloController {
    @Autowired
    MyPublisher myPublisher;
 
    @GetMapping("/test1")
    public String test1() {
        myPublisher.myPublish("Hello");
        return "test1 success";
    }
}

啟動后,訪問:http://localhost:8080/test1

后端輸出:

發(fā)布器所在線程:http-nio-8080-exec-1
監(jiān)聽器:      MyListener
  所在線程:  http-nio-8080-exec-1
  事件:      com.example.event.MyEvent[source=Hello]
  事件的數(shù)據(jù):Hello
監(jiān)聽器:      MyListener2
  所在線程:  http-nio-8080-exec-1
  事件:      com.example.event.MyEvent[source=Hello]
  事件的數(shù)據(jù):Hello

可以發(fā)現(xiàn),所有監(jiān)聽器和發(fā)布器都在同一個線程。 

同步監(jiān)聽(有序)

事件

package com.example.event;
 
import org.springframework.context.ApplicationEvent;
 
public class MyEvent extends ApplicationEvent {
 
    public MyEvent(Object source) {
        super(source);
    }
 
}

監(jiān)聽器

監(jiān)聽器1

package com.example.event;
 
import org.springframework.context.ApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
 
@Component
public class MyListener implements ApplicationListener<MyEvent>,  Ordered {
    @Override
    public void onApplicationEvent(MyEvent event) {
        System.out.println("監(jiān)聽器:      " + "MyListener");
        System.out.println("  所在線程:  " + Thread.currentThread().getName());
        System.out.println("  事件:      " + event);
        System.out.println("  事件的數(shù)據(jù):" + event.getSource());
    }
 
    @Override
    public int getOrder() {
        return 2;
    }
}

監(jiān)聽器2

package com.example.event;
 
import org.springframework.context.ApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
 
@Component
public class MyListener2 implements ApplicationListener<MyEvent>, Ordered {
 
    public void onApplicationEvent(MyEvent event) {
        System.out.println("監(jiān)聽器:      " + "MyListener2");
        System.out.println("  所在線程:  " + Thread.currentThread().getName());
        System.out.println("  事件:      " + event);
        System.out.println("  事件的數(shù)據(jù):" + event.getSource());
    }
 
    @Override
    public int getOrder() {
        return 1;
    }
}

發(fā)布器

package com.example.event;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
 
@Component
public class MyPublisher {
    @Autowired
    ApplicationContext applicationContext;
 
    public void myPublish(String message) {
        System.out.println("發(fā)布器所在線程:" + Thread.currentThread().getName());
        applicationContext.publishEvent(new MyEvent(message));
    }
}

測試

寫一個Controller

package com.example.controller;
 
import com.example.event.MyPublisher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class HelloController {
    @Autowired
    MyPublisher myPublisher;
 
    @GetMapping("/test1")
    public String test1() {
        myPublisher.myPublish("Hello");
        return "test1 success";
    }
}

啟動后,訪問:http://localhost:8080/test1

后端輸出:

發(fā)布器所在線程:http-nio-8080-exec-1
監(jiān)聽器:      MyListener2
  所在線程:  http-nio-8080-exec-1
  事件:      com.example.event.MyEvent[source=Hello]
  事件的數(shù)據(jù):Hello
監(jiān)聽器:      MyListener
  所在線程:  http-nio-8080-exec-1
  事件:      com.example.event.MyEvent[source=Hello]
  事件的數(shù)據(jù):Hello

如果將監(jiān)聽器的實現(xiàn)的Ordered順序顛倒,則輸出結(jié)果如下:

發(fā)布器所在線程:http-nio-8080-exec-1
監(jiān)聽器:      MyListener
  所在線程:  http-nio-8080-exec-1
  事件:      com.example.event.MyEvent[source=Hello]
  事件的數(shù)據(jù):Hello
監(jiān)聽器:      MyListener2
  所在線程:  http-nio-8080-exec-1
  事件:      com.example.event.MyEvent[source=Hello]
  事件的數(shù)據(jù):Hello

異步監(jiān)聽(無序)

方法:

  • 開啟異步監(jiān)聽
  • 在監(jiān)聽器上加@Async(此監(jiān)聽器必須是@Component方法注冊的)

事件

package com.example.event;
 
import org.springframework.context.ApplicationEvent;
 
public class MyEvent extends ApplicationEvent {
 
    public MyEvent(Object source) {
        super(source);
    }
 
}

同步監(jiān)聽器

package com.example.event;
 
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
 
@Component
public class MyListener {
    @EventListener
    public void abc(MyEvent event) {
        System.out.println("監(jiān)聽器:      " + "MyListener");
        System.out.println("  所在線程:  " + Thread.currentThread().getName());
        System.out.println("  事件:      " + event);
        System.out.println("  事件的數(shù)據(jù):" + event.getSource());
    }
}

異步監(jiān)聽器

package com.example.event;
 
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
 
@Component
@Async
public class MyListener2 {
 
    @EventListener
    public void onApplicationEvent(MyEvent event) {
        System.out.println("監(jiān)聽器:      " + "MyListener2");
        System.out.println("  所在線程:  " + Thread.currentThread().getName());
        System.out.println("  事件:      " + event);
        System.out.println("  事件的數(shù)據(jù):" + event.getSource());
    }
}

發(fā)布器

package com.example.event;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
 
@Component
public class MyPublisher {
    @Autowired
    ApplicationContext applicationContext;
 
    public void myPublish(String message) {
        System.out.println("發(fā)布器所在線程:" + Thread.currentThread().getName());
        applicationContext.publishEvent(new MyEvent(message));
    }
}

啟動類

package com.example;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
 
@SpringBootApplication
@EnableAsync
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

測試

寫一個Controller

package com.example.controller;
 
import com.example.event.MyPublisher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class HelloController {
    @Autowired
    MyPublisher myPublisher;
 
    @GetMapping("/test1")
    public String test1() {
        myPublisher.myPublish("Hello");
        return "test1 success";
    }
}

啟動后,訪問:http://localhost:8080/test1

后端輸出:

發(fā)布器所在線程:http-nio-8080-exec-1
監(jiān)聽器:      MyListener
  所在線程:  http-nio-8080-exec-1
  事件:      com.example.event.MyEvent[source=Hello]
  事件的數(shù)據(jù):Hello
監(jiān)聽器:      MyListener2
  所在線程:  task-1
  事件:      com.example.event.MyEvent[source=Hello]
  事件的數(shù)據(jù):Hello

到此這篇關(guān)于詳解SpringBoot實現(xiàn)同步與異步事件監(jiān)聽的文章就介紹到這了,更多相關(guān)SpringBoot事件監(jiān)聽內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論