国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 基于spring如何實現事件驅動實例代碼

基于spring如何實現事件驅動實例代碼

2021-07-29 11:50稀飯下雪 Java教程

這篇文章主要給大家介紹了關于基于spring如何實現事件驅動的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用spring具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧

干貨點

通過閱讀該篇博客,你可以了解了解java的反射機制、可以了解如何基于spring生命周期使用自定義注解解決日常研發問題。具體源碼可以點擊鏈接。

問題描述

在日常研發中,經常會遇見業務a的某個action被觸發后,同時觸發業務b的action的行為,這種單對單的形式可以直接在業務a的action執行結束后直接調用業務b的action,那么如果是單對多的情況呢?

方案解決

這里提供一種在日常研發中經常使用到的機制,基于spring實現的事件驅動,即在業務a的action執行完,拋出一個事件,而業務b、c、d等監聽到該事件后處理相應的業務。

場景范例

這里提供一個場景范例,該范例基于springboot空殼項目實現,具體可以查看源碼,此處只梳理關鍵步驟。

步驟一:

定義一個注解,標志接收事件的注解,即所有使用了該注解的函數都會在對應事件被拋出的時候被調用,該注解實現比較簡單,代碼如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * @author xifanxiaxue
 * @date 3/31/19
 * @desc 接收事件的注解
 */
@documented
@retention(retentionpolicy.runtime)
@target({elementtype.method})
public @interface receiveanno {
 
 // 監聽的事件
 class clz();
}

如果想了解注解多個參數的意義是什么的可以點擊鏈接查看博主之前寫過文章。

定義事件接口

?
1
2
3
4
5
6
7
/**
 * @author xifanxiaxue
 * @date 3/31/19
 * @desc
 */
public interface ievent {
}

所有事件都需要實現該接口,主要是為了后面泛型和類型識別。

定義methodinfo

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
 * @author xifanxiaxue
 * @date 3/31/19
 * @desc
 */
public class methodinfo {
 
 public object obj;
 public method method;
 
 public static methodinfo valueof(method method, object obj) {
 
 methodinfo info = new methodinfo();
 info.method = method;
 info.obj = obj;
 return info;
 }
 
 public object getobj() {
 return obj;
 }
 
 public method getmethod() {
 return method;
 }
}

該類只是做了object和method的封裝,沒有其他作用。

步驟二:

實現一個事件容器,該容器的作用是存放各個事件以及需要觸發的各個業務的method的對應關系。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
 * @author xifanxiaxue
 * @date 3/31/19
 * @desc 事件容器
 */
public class eventcontainer {
 
 private static map<class<ievent>, list<methodinfo>> eventlistmap = new hashmap<>();
 
 public static void addeventtomap(class clz, method method, object obj) {
 
 list<methodinfo> methodinfos = eventlistmap.get(clz);
 if (methodinfos == null) {
 methodinfos = new arraylist<>();
 eventlistmap.put(clz, methodinfos);
 }
 
 methodinfos.add(methodinfo.valueof(method, obj));
 }
 
 public static void submit(class clz) {
 
 list<methodinfo> methodinfos = eventlistmap.get(clz);
 if (methodinfos == null) {
 return;
 }
 
 for (methodinfo methodinfo : methodinfos) {
 method method = methodinfo.getmethod();
 try {
 method.setaccessible(true);
 method.invoke(methodinfo.getobj());
 } catch (illegalaccessexception e) {
 e.printstacktrace();
 } catch (invocationtargetexception e) {
 e.printstacktrace();
 }
 }
 }
}

其中的addeventtomap函數的作用是將對應的事件、事件觸發后需要觸發的對應業務內的method存放在eventlistmap內;而submit函數會在其他業務類內拋出事件的時候被調用,而作用是從eventlistmap中取出對應的method,并通過反射觸發。

步驟三:

實現事件處理器,該事件處理器的作用是在bean被spring容器實例化后去判斷對應的bean是否有相應函數加了@receiveanno注解,如果有則從中取出對應的event并放入eventcontainer中。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**
 * @author xifanxiaxue
 * @date 3/31/19
 * @desc 事件處理器
 */
@component
public class eventprocessor extends instantiationawarebeanpostprocessoradapter {
 
 @override
 public boolean postprocessafterinstantiation(object bean, string beanname) throws beansexception {
 
 reflectionutils.dowithlocalmethods(bean.getclass(), new reflectionutils.methodcallback() {
 @override
 public void dowith(method method) throws illegalargumentexception, illegalaccessexception {
 
 receiveanno anno = method.getannotation(receiveanno.class);
 if (anno == null) {
  return;
 }
 
 class clz = anno.clz();
 try {
  if (!ievent.class.isinstance(clz.newinstance())) {
  formattingtuple message = messageformatter.format("{}沒有實現ievent接口", clz);
  throw new runtimeexception(message.getmessage());
  }
 } catch (instantiationexception e) {
  e.printstacktrace();
 }
 
 eventcontainer.addeventtomap(clz, method, bean);
 }
 });
 
 return super.postprocessafterinstantiation(bean, beanname);
 }
 
}

關于instantiationawarebeanpostprocessoradapter的描述,有需要的可以查看我之前的文章,其中比較詳細描述到spring中的instantiationawarebeanpostprocessor類的作用。

步驟四:

對應的業務類的實現如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
 * @author xifanxiaxue
 * @date 3/31/19
 * @desc
 */
@slf4j
@service
public class afuncservice implements iafuncservice {
 
 @override
 public void login() {
 log.info("[{}]拋出登錄事件 ... ", this.getclass());
 eventcontainer.submit(loginevent.class);
 }
}

a業務類,login會在被調用的生活拋出loginevent事件。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 * @author xifanxiaxue
 * @date 3/31/19
 * @desc
 */
@service
@slf4j
public class bfuncservice implements ibfuncservice {
 
 @receiveanno(clz = loginevent.class)
 private void doafterlogin() {
 log.info("[{}]監聽到登錄事件 ... ", this.getclass());
 }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 * @author xifanxiaxue
 * @date 3/31/19
 * @desc
 */
@service
@slf4j
public class cfuncservice implements icfuncservice {
 
 @receiveanno(clz = loginevent.class)
 private void doafterlogin() {
 log.info("[{}]監聽到登錄事件 ... ", this.getclass());
 }
}

b和c業務類的doafterlogin都分別加了注解 @receiveanno(clz = loginevent.class) ,在監聽到事件loginevent后被觸發。
為了觸發方便,我在spring提供的測試類內加了實現,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
@runwith(springrunner.class)
@springboottest
public class eventmechanismapplicationtests {
 
 @autowired
 private afuncservice afuncservice;
 
 @test
 public void contextloads() {
 afuncservice.login();
 }
}

可以從中看出啟動該測試類后,會調用業務a的login函數,而我們要的效果是b業務類和c業務類的doafterlogin函數會被自動觸發,那么結果如何呢?

結果打印

基于spring如何實現事件驅動實例代碼

我們可以從結果打印中看到,在業務類a的login函數觸發后,業務類b和業務類c都監聽到了監聽到登錄事件,證明該機制正常解決了單對多的行為觸發問題。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對服務器之家的支持。

原文鏈接:https://juejin.im/post/5ca9c0bf6fb9a05e462ba780

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 欧美亚洲国产一区二区三区 | 欧美国产精品一区二区三区 | www.亚洲成人 | 91国内外精品自在线播放 | 亚洲视频中文字幕 | 欧美一区二区三区在线观看 | 日本高清视频网站www | 久久久精品视频国产 | 另类视频区 | 99精品一区二区三区 | 巴西性猛交xxxx免费看久久久 | 久久久久久久久国产成人免费 | 久久h| 中文字幕亚洲专区 | 色综合中文 | 亚洲精品无 | av在线日韩 | 欧美视频免费看 | 综合久久综合久久 | 久久99精品视频 | 亚洲一区二区福利 | 免费在线成人 | 久久久久一区 | 色视频www在线播放国产人成 | 91粉色视频 | 日b片| 国产视频久久 | 人人澡人人射 | 久色| 国产a√ | 日韩在线看片 | 制服诱惑一区二区 | 中文字幕66页 | 久久精品亚洲精品 | 国产午夜精品一区二区三区视频 | 色就是色欧美 | 在线a视频网站 | 欧美三级在线 | 欧美激情综合五月色丁香小说 | 日韩码有限公司在线观看 | 亚洲人人射 |