老熟女激烈的高潮_日韩一级黄色录像_亚洲1区2区3区视频_精品少妇一区二区三区在线播放_国产欧美日产久久_午夜福利精品导航凹凸

重慶分公司,新征程啟航

為企業提供網站建設、域名注冊、服務器等服務

Spring事件發布與監聽怎么實現

這篇文章主要講解了“Spring事件發布與監聽怎么實現”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Spring事件發布與監聽怎么實現”吧!

讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業的熱愛。我們立志把好的技術通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領域值得信任、有價值的長期合作伙伴,公司提供的服務項目有:國際域名空間、虛擬主機、營銷軟件、網站建設、汾陽網站維護、網站推廣。

一、事件監聽相關概念介紹

1、流程分析

事件:做了什么事。例如,我在寫博客,寫博客就是一個事件。

監聽器:監聽發生事件的組件。例如,我們日常生活中的火災報警器,監聽有沒有發生火災事件。

在一個完整的事件體系中,除了事件和監聽器以外,還應該有3個概念;

1. 事件源:事件的產生者,任何一個event都必須有一個事件源;

2. 事件廣播器:它是事件和事件監聽器之間的橋梁,負責把事件通知給事件監聽器;

3. 事件監聽器注冊表:就是spring框架為所有的監聽器提供了一個存放的地方;

通過流程圖,可以看出它們是如何各司其職的,如下:

Spring事件發布與監聽怎么實現

其實通過流程圖,我們很容易發現事件體系就是觀察者模式的具體實現,它并沒有任何的神秘之處。

2、流程分析

結構分析:

1. 事件類(ApplicaitonEvent):目前spring框架本身僅僅提供了幾個事件,很多的事件都是需要自定義的。

ApplicationEvent唯一的構造函數是ApplicaitonEvent(Object source),通過source指定事件源。 它有兩個子類;

(1)ApplicationContextEvent:容器事件,也就是說事件源是ApplicationContext,框架提供了四個子類,分別代表容器啟動,刷新,停止和關閉事件。

(2)RequestHandleEvent:這是一個與Web應用相關的事件,當一個請求被處理后,才會產生該事件。

一般來說,我們都是擴展ApplicationEvent來自定義事件。下面會有栗子。

Spring事件發布與監聽怎么實現

2. 事件監聽器接口(ApplicationListener)

所有的監聽器都需要實現該接口,該接口只定義了一個方法:onApplicaitonEvent (E event),該方法接收事件對象,在該方法中編寫事件的響應處理邏輯。

Spring事件發布與監聽怎么實現

二、手寫模擬事件發布與監聽

注:想直接了解Spring事件監聽與發布的,可以跳過這節,但是我建議你還是看一下。

需求:

假設現在公司讓你開發一個文件操作幫助類 ,

定義一個文件讀寫方法 讀寫某個文件 寫到某個類里面去 //但是 有時候可能會需要記錄文件讀取進度條的需求

有時候需要進度條 如何實現?

答案:我們可以采用事件發布與監聽。

事件:文件上傳

事件源:事件在哪里發布的,比如說我們在A類中,發布了事件。那么A類的對象就是事件源。

監聽器:我們編寫的FileUploadListener對這個事件進行了監聽。并在監聽到了當前事件之后,發布事件。

代碼編寫:

/**

* @ClassName ApplicationEvent

* @Description

* @Author EvanWang

* @Version 1.0.0

* @Date 2019/12/9 20:29

*/

public class ApplicationEvent {

}

/**

* @ClassName ApplicationListener

* @Description

* @Author EvanWang

* @Version 1.0.0

* @Date 2019/12/9 20:29

*/

public interface ApplicationListener {

void onEvent(E e);

}

/**

* @ClassName ListenerManage

* @Description

* @Author EvanWang

* @Version 1.0.0

* @Date 2019/12/9 20:44

*/

//事件管理器

public class ListenerManage {

//保存所有的監聽器

static List> list = new ArrayList<>();

//添加監聽器 注:如果要做的更加優雅,應該做成掃描全局,通過掃描將所有的監聽器放入管理器的容器列表,這里為了方便演示就不做復雜了。

//springboot是從spring的BeanFactory中獲取listener

public static void addListener(ApplicationListener listener) {

list.add(listener);

}

//判斷一下 有哪些監聽器 監聽了這個事件

public static void publishEvent(ApplicationEvent event) {

for (ApplicationListener applicationListener : list) {

//獲取ApplicationListener的泛型

Class typeParameter = (Class) ((ParameterizedType) applicationListener.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0];

if (typeParameter.equals(event.getClass())) {

applicationListener.onEvent(event);

}

}

}

}

/**

* @ClassName FileUploadEvent

* @Description

* @Author EvanWang

* @Version 1.0.0

* @Date 2019/12/9 21:37

*/

public class FileUploadEvent extends ApplicationEvent {

private int fileSize;

private int readSize;

public FileUploadEvent(int fileSize, int readSize) {

this.fileSize = fileSize;

this.readSize = readSize;

}

public int getFileSize() {

return fileSize;

}

public void setFileSize(int fileSize) {

this.fileSize = fileSize;

}

public int getReadSize() {

return readSize;

}

public void setReadSize(int readSize) {

this.readSize = readSize;

}

}

/**

* @ClassName FileUploadListener

* @Description

* @Author EvanWang

* @Version 1.0.0

* @Date 2019/12/9 21:38

*/

public class FileUploadListener implements ApplicationListener {

@Override

public void onEvent(FileUploadEvent fileUploadEvent) {

double molecule = fileUploadEvent.getFileSize();

double denominator = fileUploadEvent.getReadSize();

System.out.println("當前文件上傳進度百分比:" + (denominator / molecule * 100 + "%"));

}

}

/**

* @ClassName FileUtil

* @Description

* @Author EvanWang

* @Version 1.0.0

* @Date 2019/12/9 17:06

*/

public class FileUtil {

public static int READ_SIZE = 100;

public static void fileWrite(InputStream is, OutputStream os) throws Exception {

fileWrite(is, os, null);

}

public static void fileWrite(InputStream is, OutputStream os, FileListener fileListener) throws Exception {

BufferedInputStream bis = new BufferedInputStream(is);

BufferedOutputStream bos = new BufferedOutputStream(os);

/**

* 如果是網絡請求最好不要用這個方法拿fileSize,因為這個方法會產生阻塞。最好傳一個File對象進來。

* 這里作為演示,就不去處理細節了。

*/

//文件總大小

int fileSize = is.available();

//一共讀取了多少

int readSize = 0;

byte[] readedBytes = new byte[READ_SIZE];

//控制是否退出

boolean exit = true;

while (exit) {

//文件小于第一次讀的大小的時候

if (fileSize < READ_SIZE) {

byte[] fileBytes = new byte[fileSize];

//將緩沖區中的數據寫入到字節數組fileBytes中

bis.read(fileBytes);

//向文件寫入fileBytes數組的內容

bos.write(fileBytes);

readSize = fileSize;

exit = false;

//當你是最后一次讀的時候

} else if (fileSize < readSize + READ_SIZE) {

byte[] bytes = new byte[fileSize - readSize];

readSize = fileSize;

bis.read(bytes);

bos.write(bytes);

exit = false;

} else {

bis.read(readedBytes);

readSize += READ_SIZE;

bos.write(readedBytes);

}

//發布事件

ListenerManage.publishEvent(new FileUploadEvent(fileSize, readSize));

if (fileListener != null) {

fileListener.updateLoad(fileSize, readSize);

}

}

bis.close();

bos.close();

}

}

/**

* @ClassName FileReadTest

* @Description

* @Author EvanWang

* @Version 1.0.0

* @Date 2019/12/9 18:26

*/

public class FileReadTest {

public static void main(String[] args) throws Exception {

ListenerManage.addListener(new FileUploadListener());

//這里根據實際情況去設置讀寫的文件

File file = new File("F:\\測試寫出.txt");

if (!file.exists()) {

file.createNewFile();

}

//如果需要做進度條功能,再添加一個fileListener參數

fileWrite(new FileInputStream(new File("F:\\明天要做的事.txt")), new FileOutputStream(file));

}

}

運行結果:

當前文件上傳進度百分比:14.245014245014245%

當前文件上傳進度百分比:28.49002849002849%

當前文件上傳進度百分比:42.73504273504273%

當前文件上傳進度百分比:56.98005698005698%

當前文件上傳進度百分比:71.22507122507122%

當前文件上傳進度百分比:85.47008547008546%

當前文件上傳進度百分比:99.71509971509973%

當前文件上傳進度百分比:100.0%

三、Spring的時間發布與監聽

我們在上面手動模擬了Spring的時間發布與監聽后,看如果上面的例子后,我們使用Spring再寫一個事件發布與監聽的例子。鄭州人流醫院 http://rl.zyfuke.com/

package com.evan.spring.config;

import org.springframework.context.annotation.ComponentScan;

/**

* @ClassName Appconfig

* @Description

* @Author EvanWang

* @Version 1.0.0

* @Date 2019/12/10 16:04

*/

@ComponentScan("com")

public class AppConfig {

}

package com.evan.spring.event;

import org.springframework.context.ApplicationContext;

import org.springframework.context.event.ApplicationContextEvent;

import org.springframework.context.event.ContextStartedEvent;

/**

* @ClassName MyEvent

* @Description

* @Author EvanWang

* @Version 1.0.0

* @Date 2019/12/10 15:39

*/

public class WriteBlogEvent extends ApplicationContextEvent {

String name;

String address;

public WriteBlogEvent(ApplicationContext source, String name, String address) {

super(source);

this.name = name;

this.address = address;

}

public String getName() {

return name;

}

public String getAddress() {

return address;

}

}

Spring的事件監聽可以基于注解或實現接口。對于同一個事件,如果兩個都存在,相當于多個監聽器監聽一個事件。

兩個監聽器內的方法都會執行。

package com.evan.spring.listener;

import com.evan.spring.event.WriteBlogEvent;

import org.springframework.context.ApplicationListener;

import org.springframework.stereotype.Component;

/**

* @ClassName WriteBlogListener

* @Description

* @Author EvanWang

* @Version 1.0.0

* @Date 2019/12/10 15:47

*/

@Component

public class WriteBlogListener implements ApplicationListener {

@Override

public void onApplicationEvent(WriteBlogEvent writeBlogEvent) {

String name = writeBlogEvent.getName();

String address = writeBlogEvent.getAddress();

System.out.println("基于實現接口:" + name + "在" + address + "寫了一篇博客");

}

}

package com.evan.spring.listener;

import com.evan.spring.event.WriteBlogEvent;

import org.springframework.context.event.EventListener;

import org.springframework.stereotype.Component;

/**

* @ClassName WriteBlogListenerAnnotation

* @Description

* @Author EvanWang

* @Version 1.0.0

* @Date 2019/12/10 16:30

*/

@Component

public class WriteBlogListenerAnnotation {

@EventListener

public void annotationListen(WriteBlogEvent writeBlogEvent) {

String name = writeBlogEvent.getName();

String address = writeBlogEvent.getAddress();

System.out.println("基于注解:" + name + "在" + address + "寫了一篇博客");

}

}

package com.evan.spring.test;

import com.evan.spring.config.AppConfig;

import com.evan.spring.event.WriteBlogEvent;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**

* @ClassName EventTest

* @Description

* @Author EvanWang

* @Version 1.0.0

* @Date 2019/12/10 15:56

*/

public class EventTest {

public static void main(String[] args) {

AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

WriteBlogEvent writeBlogEvent = new WriteBlogEvent(ac, "Evan", "家里");

ac.publishEvent(writeBlogEvent);

}

}

運行結果:

基于注解:Evan在家里寫了一篇博客

基于實現接口:Evan在家里寫了一篇博客

四、總結

1、spring 如何得知有哪些監聽器?

通過2個步驟:1.從Bean工廠拿到所有ApplicationListener類型的Bean.

2.掃描所有帶@EventListener

2、spring如何發布事件?

大邏輯上通過2個步驟: 1.判斷是否有監聽器對該事件感興趣

2.調用監聽器方法

感謝各位的閱讀,以上就是“Spring事件發布與監聽怎么實現”的內容了,經過本文的學習后,相信大家對Spring事件發布與監聽怎么實現這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創新互聯,小編將為大家推送更多相關知識點的文章,歡迎關注!


分享名稱:Spring事件發布與監聽怎么實現
鏈接地址:http://www.xueling.net.cn/article/gocdpi.html

其他資訊

在線咨詢
服務熱線
服務熱線:028-86922220
TOP
主站蜘蛛池模板: 成人全黄A片免费看香港 | 99久久久国产精品免费消防器 | 91精选在线观看 | 91大片在线观看 | 亚洲综合在线视频 | GOGOGO高清在线观看免费 | 亚洲狠狠婷婷综合久久久久图片 | 奇米影视777me| 日本一区二区三区爆乳 | 热久久国产精品 | 国产精品爆乳奶水无码视频 | 暖暖在线日本免费中文 | 亚洲色无码A片一区二小说 久久九九影视 | 99国产精品久久久久久久 | 婬荡少妇21P | AV经典动态高潮GIF图无码 | GOGOGO免费高清看中国国语 | 亚洲AV美日韩AV丝袜美腿 | 国产激情网站 | 国产小视频免费观看 | 亚洲一区二区三区偷拍女厕 | 国农村精品国产自线拍 | 亚洲AV无码男人的天堂在线 | 色欲AV永久无码精品无码蜜桃 | 黄色真人毛片 | 午夜影院免费版 | 91大神在线免费?看 h免费看 | 久久精品久久久久久久 | 蜜臀久久99精品久久久久久9 | 亚洲AV永久中文无码精品 | 午夜免费视频网站 | 国产69精品久久久久久野外 | 久久久综合久久久 | 正在播放东北夫妻内射 | 国产freexxxx性播放古装 | www.97超碰| 国产露脸饥渴孕妇在线播放 | 日本aa在线 | 91视频分类 | 日本专区在线观看 | 国产国拍亚洲精品av在线 |