Spring的事件機(jī)制

當(dāng)把一個(gè)事件發(fā)布到Spring提供的ApplicationContext中,被監(jiān)聽(tīng)器偵測(cè)到,就會(huì)執(zhí)行對(duì)應(yīng)的處理方法。

事件本身

事件是一個(gè)自定義的類,需要繼承Spring提供的ApplicationEvent。

@Data
public class MyEvent extends ApplicationEvent {
    private String msg;

    public MyEvent(Object source, String msg) {
        super(source);
        this.msg = msg;
    }
}

事件監(jiān)聽(tīng)

基本方法是實(shí)現(xiàn)ApplicationListener接口,自定義一個(gè)監(jiān)聽(tīng)器,實(shí)現(xiàn)onApplicationEvent()方法,然后添加到ApplicationContext。
比如:

public class MyListener implements ApplicationListener<MyEvent> {  

    @Override  
    public void onApplicationEvent(MyEvent event) {  
        System.out.print("監(jiān)聽(tīng)到MyEvent事件");  
    }  
}  
...
// SpringBoot的啟動(dòng)類中添加監(jiān)聽(tīng)器
        public static void main(String[] args) {
        SpringApplication application = new SpringApplication(MyApplication.class);
        application.addListeners(new MyListener());
        application.run(args);
    }

也可以使用注解@EventListener(推薦):原理就是通過(guò)掃描這個(gè)注解,創(chuàng)建監(jiān)聽(tīng)器并添加到ApplicationContext。

@Component
@Slf4j
public class MyEventHandler {

    @EventListener
    public void handleEvent(MyEvent event) {
        log.info("------------處理事件:{}", event.getMsg());
        try {
            Thread.sleep(5 * 1000L);
            log.info("事件1(5s)處理完成");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

事件發(fā)布

可以通過(guò)上下文對(duì)象的發(fā)布方法ConfigurableApplicationContext::publishEvent()來(lái)發(fā)布。
也可以實(shí)現(xiàn)ApplicationEventPublisherAware接口來(lái)發(fā)布(推薦)。

@Component
@Slf4j
public class EventService implements ApplicationEventPublisherAware {
    public ApplicationEventPublisher publisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.publisher = applicationEventPublisher;
    }

    public String doEventWork(String msg) {
        log.info("------------publish event:" + msg);
        MyEvent event = new MyEvent(this, msg);
        publisher.publishEvent(event);
        return "OK";
    }
}

測(cè)試代碼

@SpringBootTest
@RunWith(SpringRunner.class)
public class EventServiceTest {
    @Autowired
    private EventService service;

    @Test
    public void eventTest() {
        String msg="Java Code";
        service.doEventWork(msg);
    }
}
image

注意

如果2個(gè)事件之間是繼承關(guān)系,會(huì)先監(jiān)聽(tīng)到子類事件,處理完再監(jiān)聽(tīng)父類。

// MyEvent2 extends MyEvent

@Component
@Slf4j
public class MyEventHandler {

    @EventListener
    public void handleEvent(MyEvent event) {
        log.info("------------處理事件:{}", event.getMsg());
        try {
            Thread.sleep(5 * 1000L);
            log.info("事件1(5s)處理完成");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @EventListener
    public void handleEvent2(MyEvent2 event) {
        log.info("------------處理事件2:{}", event.getMsg());
        try {
            Thread.sleep(10 * 1000L);
            log.info("事件2(10s)處理完成");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

當(dāng)我publish一個(gè)子類事件MyEvent2時(shí),日志如下:


image

默認(rèn)是同步事件,如要使用異步,需要開(kāi)啟異步,并使用@Async

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,534評(píng)論 19 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,261評(píng)論 6 342
  • 1.1 spring IoC容器和beans的簡(jiǎn)介 Spring 框架的最核心基礎(chǔ)的功能是IoC(控制反轉(zhuǎn))容器,...
    simoscode閱讀 6,846評(píng)論 2 22
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong閱讀 22,939評(píng)論 1 92
  • 渾渾噩噩的過(guò)了幾個(gè)月,至少我是這樣認(rèn)為的,總想著寫(xiě)些什么東西,以為自己想寫(xiě)就一定會(huì)寫(xiě),每當(dāng)提起筆來(lái),空洞的...
    露出了真身可會(huì)被抱緊閱讀 365評(píng)論 2 2

友情鏈接更多精彩內(nèi)容