Spring自定義事件發佈-監聽

本人Git地址:https://github.com/a422478514/java-practice/tree/master/src/main/java/com/daquan/_202007/_01/spring/event

一、監聽器模式

監聽者通過向發佈者註冊自身(自身可以理解爲監聽者對象),如果有事件發生,發佈者會調用註冊列表裏的監聽者的某方法並把事件(事件內部持有事件源)作爲參數傳入。

在Spring中需要我們自己定義事件監聽器、事件。發佈器不需要自定義,但需要設法通過上下文拿到發佈器。(可以思考下爲什麼這麼設計?)

二、基於Spring實現的消息監聽類圖詳解

1、事件:

EventObject:是JDK自帶的事件,是個具體的類,本身持有一個Object事件源用來定義本次事件的具體描述。EventObject本身是事件源的容器。

ApplicationEvent:是對EventObject的簡單封裝(擴展),但是是個抽象類,用來作爲自定義事件類的基類,這樣設計也是爲了滿足對監聽器對具體某自定義事件的監聽。該類構造函數裏調用了super(source)用來封裝事件源,並提供了一個返回當前時間的方法。

MySpringApplicationEvent:是自定義的事件類,也是本次講解中要被監聽的事件。其構造函數需要的參數同樣是自定義的事件源。

2、發佈者容器:

Aware是個空接口,用來方便擴展,也是Spring的慣用操作

ApplicationEventPublisherAware是Spring中用來識別注入ApplicationEventPublisher對象的特殊接口。(一般xxxxxAware都是用來給實現類注入xxxxx的)

MySpringEventPublisherContext是自定義的發佈者容器,裏面封裝了Spring提供的事件發佈器

3、監聽者

EventListener:Spring提供的空接口

ApplicationListener:繼承了EventListener且通過使用泛型來實現針對某一具體事件類型的監聽,onApplicationEvent作爲事件觸發時調用的函數。

4、自定義事件源

MyEventSource是事件源的具體實現,是事件的核心內容,該類持有大部分有效信息。

三、代碼

1、MyEventSource.java

/**
 * 用來描述事件源的實體類
 */
public class MyEventSource implements Serializable {
    private static final long serialVersionUID = 1L;
    private int id;
    private String name;

    public MyEventSource(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "MyEventSource{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

2、MySpringApplicationEvent.java

import org.springframework.context.ApplicationEvent;

/**
 * 使用spring事件框架自定義的事件
 */
public class MySpringApplicationEvent extends ApplicationEvent {
    public MySpringApplicationEvent(MyEventSource eventSource) {
        super(eventSource);
    }
}

3、MySpringApplicationListener.java

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Service;

/**
 * 基於Spring事件框架自定義的事件監聽器,注意泛型用來確定要監聽的事件
 */
@Service
public class MySpringApplicationListener implements ApplicationListener<MySpringApplicationEvent> {
    @Override
    public void onApplicationEvent(MySpringApplicationEvent mySpringApplicationEvent) {
        System.out.println("監聽到事件:"+mySpringApplicationEvent.getSource().toString());
    }
}

4、MySpringEventPublisherContext.java


import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;

/**
 * 事件發佈器上下文
 */
@Service
public class MySpringEventPublisherContext implements ApplicationEventPublisherAware {

    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        System.out.println("注入事件發佈器");
        this.applicationEventPublisher = applicationEventPublisher;
    }

    public ApplicationEventPublisher getApplicationEventPublisher() {
        return applicationEventPublisher;
    }
}

5、TestSpringEventMain.java

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 測試SpringEvent的啓動器
 */
public class TestSpringEventMain {
    public static void main(String[] args) {
        System.out.println("1、加載spring容器");
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("application.xml");
        System.out.println("2、從容器中獲取事件發佈器");
        MySpringEventPublisherContext publisherContext = classPathXmlApplicationContext.getBean(MySpringEventPublisherContext.class);
        System.out.println("3、發佈事件");
        publisherContext.getApplicationEventPublisher().publishEvent(new MySpringApplicationEvent(new MyEventSource(1,"daquan")));

    }
}

6、配置文件 application.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.1.xsd">


    <context:annotation-config />
    <!--自動掃描含有@Service將其注入爲bean -->
    <context:component-scan base-package="com.daquan._202007" />

</beans>

運行5、結果如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章