激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

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

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

服務器之家 - 編程語言 - Java教程 - java使用觀察者模式異步短信/郵箱提醒用戶群

java使用觀察者模式異步短信/郵箱提醒用戶群

2021-06-14 14:21沒有不憂傷的故事 Java教程

這篇文章主要為大家詳細介紹了java使用觀察者模式異步短信和郵箱提醒用戶群,具有一定的參考價值,感興趣的小伙伴們可以參考一下

需求

用戶中有人設置了賬戶余額達到閾值時,短信/郵箱進行提醒的服務。我們將需要在他賬戶余額閾值達到指定數值的時候進行短信/郵箱消息通知,允許賬戶余額閾值出現偏差的時候通知,如果某個用戶48小時內已經短信/郵箱進行過通知了,那么將不再進行通知。

剖析

  • 存在兩個主題:短信通知和郵箱通知
  • 存在兩種觀察者:設置了短信通知且賬戶余額到達閾值的用戶,設置了郵箱通知且賬戶余額到達閾值的用戶。
  • 用spring的定時器,每10分鐘去數據庫獲取某個主題已經達到閾值且開始了該主題的提醒功能的用戶
  • 用spring的@asycn注解異步短信通知,郵箱通知的相關方法
  • 用redis設置用戶短信/郵箱為鍵名,設置過期時間為48小時。如果獲取不到該鍵值對,說明其在觀察者行列

代碼

觀察者父類

 

?
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
 * 訂閱觀察者
 * @author administrator
 *
 */
@component
//標志為多例
@scope(value=configurablebeanfactory.scope_prototype)
public class subscriberobserver implements observer{
 
  private string email;
  private string phone;
  private string username;
  @autowired
  userfunctionservice userfunctionservice;
 
 
  @override
  public void update(observable o, object arg) {
    if(o instanceof emailalertsubject){
      userfunctionservice.alertuseremail(email,username);
    }
    if(o instanceof phonealertsubject){
      userfunctionservice.alertuserphone(phone,username);
    }
  }
 
  public string getemail() {
    return email;
  }
 
  public void setemail(string email) {
    this.email = email;
  }
 
  public string getphone() {
    return phone;
  }
 
  public void setphone(string phone) {
    this.phone = phone;
  }
 
  public string getusername() {
    return username;
  }
 
  public void setusername(string username) {
    this.username = username;
  }
 
  public subscriberobserver() {
    super();
    // todo auto-generated constructor stub
  }
 
 
}

主題

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 * email提醒主題
 * @author administrator
 *
 */
@component
public class emailalertsubject extends observable{
 
  public void alert(){
     this.setchanged();
     //如果用拉的方式,這么調用
     this.notifyobservers();
  }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 * 短信提醒主題
 * @author administrator
 *
 */
@component
public class phonealertsubject extends observable{
 
  public void alert(){
     this.setchanged();
     //如果用拉的方式,這么調用
     this.notifyobservers();
  }
}

定時器

 

?
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/**
 * 定時給訂閱了短信提醒和email提醒的用戶服務
 * @author administrator
 *
 */
@component
public class timealerttaskutil {
 
  @autowired
  commonuserservice commonuserservice;
  @autowired
  jedisconnectionfactory factory;
  @autowired
  emailalertsubject emailsubject;
  @autowired
  phonealertsubject phonesubject;
 
 
  private static final string emailkeyname = "emailalert:";
  private static final string phonekeyname = "phonealert:";
 
  /**
   * 定時獲取需要email提醒的用戶,每10分鐘調用一次
   */
  @scheduled(fixeddelay = 1000 * 60 * 10)
  public void alertemailtask() {
    // 1.獲取數據庫中達到了閾值的用戶
    list<user> emails = commonuserservice.getuseralertemailandname();
    // 2.查看redis中是否有達到閾值,且48小時已經通知的用戶,將其排除在觀察者行列,最終得出觀察者隊伍
    list<subscriberobserver> informemail = getinformobserver(emails);
    // 3.創建主題,添加觀察者
    addobservers(emailsubject, informemail);
    // 4.通知
    emailsubject.alert();
 
    // 5.將已經通知的觀察者信息存儲到reids內,設置過期時間為一天
    setrediscache(emails);
    // 6.將觀察者從主題中移除
    deleteobservers(emailsubject, informemail);
  }
 
  /**
   * 定時獲取需要短信提醒的用戶,每10分鐘調用一次
   *
   */
  @scheduled(fixeddelay = 1000 * 60 * 10)
  public void alertphonetask() {
    // 1.獲取數據庫中達到了閾值的用戶
    list<user> phones = commonuserservice.getuseralertphoneandname();
    // 2.查看redis中是否有達到閾值,且今天已經通知的用戶,將其排除在觀察者行列,最終得出觀察者隊伍
    list<subscriberobserver> informphones = getinformobserver(phones);
 
    // 3.創建主題,添加觀察者
    addobservers(phonesubject, informphones);
    // 4.通知
    phonesubject.alert();
    // 5.將已經通知的觀察者信息存儲到reids內,設置過期時間為一天
    setrediscache(phones);
    // 6.將觀察者從主題中移除
    deleteobservers(phonesubject, informphones);
  }
 
  /**
   * ------------------------------------------------------------------------
   * -----------------------------------------------------
   **/
  /**
   * 過濾掉今天已經email提醒的用戶,返回真正需要提醒的觀察者列表
   *
   * @param emails
   * @return
   */
  private list<subscriberobserver> getinformobserver(
      list<user> users) {
    list<subscriberobserver> obs = new arraylist<subscriberobserver>();
    jedis jedis = factory.getconnection().getnativeconnection();
    for (user user : users) {
      string value;
      subscriberobserver observer = (subscriberobserver) springconfigtool
          .getbean("subscriberobserver");
      if (user.getemail()!=null) {
        value = jedis.get(emailkeyname + user.getemail());
        if (value == null || !value.equals("success")) {
          observer.setemail(user.getemail());
          observer.setusername(user.getname());
          obs.add(observer);
        }
      } else {
        value = jedis.get(phonekeyname + user.getphone());
        if (value == null || !value.equals("success")) {
          observer.setphone(user.getphone());
          observer.setusername(user.getname());
          obs.add(observer);
        }
      }
    }
    return obs;
  }
 
  /**
   * 將指定的觀察者列表添加到指定的主題
   *
   * @param subject
   * @param list
   */
  private void addobservers(observable subject, list<subscriberobserver> list) {
    for (subscriberobserver obs : list) {
      subject.addobserver(obs);
    }
  }
 
  private void deleteobservers(observable subject,
      list<subscriberobserver> list) {
    for (subscriberobserver obs : list) {
      subject.deleteobserver(obs);
    }
  }
 
  /**
   * 將列表的值作為鍵,存入redis,過期時間為48小時
   *
   * @param list
   */
  private void setrediscache(list<user> users) {
    jedis jedis = factory.getconnection().getnativeconnection();
    for (user user : users) {
      if (user.getemail()!=null) {
        jedis.set(emailkeyname + user.getemail(), "success", "nx", "ex",
            60 * 60 * 24 * 2);
      } else {
        jedis.set(phonekeyname + user.getphone(), "success", "nx", "ex",
            60 * 60 * 24 * 2);
      }
    }
  }
}

總結

代碼是不全面的,只是個示例而已。關于短信通知和郵箱通知的服務類和工具類并沒有給出,因為里面涉及到一些隱私參數。所以關于異步通知示例代碼沒有,但使用spring管理的@async注解和在spring進行一定的配置即可,可以在我的另外一篇博客找到關于異步通知的示例代碼。

事實上根據需求,可以使用redis的發布訂閱,或者消息隊列mq來實現類似的功能。但為了加深對設計模式的理解,所以寫了一個不是很純正的觀察者模式來模仿發布訂閱的操作。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/qq_32020035/article/details/81204374

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品6区 | 深夜影院一级毛片 | 免费毛片随便看 | 一级毛片免费高清视频 | 日韩在线播放一区二区 | 一级做受大片免费视频 | 偷偷草网站| 日本在线观看一区二区 | 日韩视频不卡 | 在线无码 | 精品欧美一区二区精品久久 | 亚洲成人福利电影 | 久久99精品久久久久久园产越南 | 九一国产精品 | 99影视在线视频免费观看 | 亚洲免费在线视频 | 日日爱夜夜操 | 国产91久久久久久 | 看国产毛片 | 最近免费观看高清韩国日本大全 | 黄色一级电影网 | 轻点插视频 | 国产1区2区在线 | 精品一区二区三区不卡 | 中国黄色一级生活片 | 激情宗合| 日日狠狠久久偷偷四色综合免费 | av成人一区二区 | 一本色道久久综合亚洲精品图片 | 亚洲射情 | 日产精品久久久久久久 | 9797色| 草草久久久 | 欧美亚洲免费 | 在线成人精品视频 | 日韩一级片一区二区三区 | 欧美亚州| 91久久久久久久久久久久久久 | 毛片免费观看日本中文 | 综合毛片| 视频在线亚洲 |