1. 程式人生 > 其它 >Spring 中的事件機制 ApplicationEventPublisher

Spring 中的事件機制 ApplicationEventPublisher

Spring 中的事件機制 ApplicationEventPublisher
      事件機制在一些大型專案中被經常使用,於是 Spring 專門提供了一套事件機制的介面,方便我們運用。本文來說說 ApplicationEventPublisher 的使用。
在設計模式中,觀察者模式可以算得上是一個非常經典的行為型設計模式,貓叫了,主人醒了,老鼠跑了,這一經典的例子,是事件驅動模型在設計層面的體現。另一模式,釋出訂閱模式往往被人們等同於觀察者模式,但我的理解是兩者唯一區別,是釋出訂閱模式需要有一個排程中心,而觀察者模式不需要,例如觀察者的列表可以直接由被觀察者維護。不過兩者即使被混用,互相替代,通常不影響表達。Java 和 spring 中都擁有 Event 的抽象,分別代表了語言級別和三方框架級別對事件的支援。

Spring 的文件對 Event 的支援翻譯之後描述如下:

ApplicationContext 通過 ApplicationEvent 類和 ApplicationListener 介面進行事件處理。 如果將實現 ApplicationListener 介面的 bean 注入到上下文中,則每次使用 ApplicationContext 釋出 ApplicationEvent 時,都會通知該 bean。本質上,這是標準的觀察者設計模式

下面通過 demo,看一個電商系統中對 ApplicationEventPublisher 的使用。我們的系統要求,當用戶註冊後,給他傳送一封郵件通知他註冊成功了。然後給他初始化積分,發放一張新使用者註冊優惠券等。

定義一個使用者註冊事件:

public class UserRegisterEvent extends ApplicationEvent{
public UserRegisterEvent(String name) { //name即source
super(name);
}
}

ApplicationEvent 是由 Spring 提供的所有 Event 類的基類,為了簡單起見,註冊事件只傳遞了 name(可以複雜的物件,但注意要了解清楚序列化機制)。

再定義一個使用者註冊服務(事件釋出者):

@Service
public class UserService implements ApplicationEventPublisherAware {
public void register(String name) { System.out.println("使用者:" + name + " 已註冊!"); applicationEventPublisher.publishEvent(new UserRegisterEvent(name)); } private ApplicationEventPublisher applicationEventPublisher; @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.applicationEventPublisher = applicationEventPublisher; } }

 

需要注意的是,服務必須交給 Spring 容器託管。ApplicationEventPublisherAware 是由 Spring 提供的用於為 Service 注入 ApplicationEventPublisher 事件釋出器的介面,使用這個介面,我們自己的 Service 就擁有了釋出事件的能力。使用者註冊後,不再是顯示呼叫其他的業務 Service,而是釋出一個使用者註冊事件。

建立郵件服務,積分服務,其他服務(事件訂閱者)等:

@Service
public class EmailService implements ApplicationListener<UserRegisterEvent> {
   @Override
   public void onApplicationEvent(UserRegisterEvent userRegisterEvent) {
    System.out.println("郵件服務接到通知,給 " + userRegisterEvent.getSource() + " 傳送郵件...");
  }
}

 

事件訂閱者的服務同樣需要託管於 Spring 容器,ApplicationListener 介面是由 Spring 提供的事件訂閱者必須實現的介面,我們一般把該 Service 關心的事件型別作為泛型傳入。處理事件,通過 event.getSource() 即可拿到事件的具體內容,在本例中便是使用者的姓名。 其他兩個 Service,也同樣編寫,實際的業務操作僅僅是列印一句內容即可,篇幅限制,這裡省略。

最後我們使用 Springboot 編寫一個啟動類。

@SpringBootApplication
@RestController
public class EventDemoApp {
   public static void main(String[] args) {
    SpringApplication.run(EventDemoApp.class, args);
    }
@Autowired
UserService userService;
@RequestMapping("/register")
public String register(){
      userService.register("xttblog.com");
      return "success";
     }
}

 

至此,一個電商系統中簡單的事件釋出訂閱就完成了,後面無論如何擴充套件,我們只需要新增相應的事件訂閱者即可。
————————————————
版權宣告:本文為CSDN博主「巨行心」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/ssssny/article/details/104640105