Spring 中的事件機制 ApplicationEventPublisher

系列文章首發公主號java

事件機制在一些大型項目中被常常使用,因而 Spring 專門提供了一套事件機制的接口,方便咱們運用。本文來講說 ApplicationEventPublisher 的使用。spring

在設計模式中,觀察者模式能夠算得上是一個很是經典的行爲型設計模式,貓叫了,主人醒了,老鼠跑了,這一經典的例子,是事件驅動模型在設計層面的體現。設計模式

另外一模式,發佈訂閱模式每每被人們等同於觀察者模式,但個人理解是二者惟一區別,是發佈訂閱模式須要有一個調度中心,而觀察者模式不須要,例如觀察者的列表能夠直接由被觀察者維護。不過二者即便被混用,互相替代,一般不影響表達。app

java 和 spring 中都擁有 Event 的抽象,分別表明了語言級別和三方框架級別對事件的支持。框架

Spring 的文檔對 Event 的支持翻譯以後描述以下:ide

ApplicationContext 經過 ApplicationEvent 類和 ApplicationListener 接口進行事件處理。 若是將實現 ApplicationListener 接口的 bean 注入到上下文中,則每次使用 ApplicationContext 發佈 ApplicationEvent 時,都會通知該 bean。本質上,這是標準的觀察者設計模式。this

下面經過 demo,看一個電商系統中對 ApplicationEventPublisher 的使用。spa

咱們的系統要求,當用戶註冊後,給他發送一封郵件通知他註冊成功了。翻譯

而後給他初始化積分,發放一張新用戶註冊優惠券等。設計

定義一個用戶註冊事件:

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";
    }
}
複製代碼

至此,一個電商系統中簡單的事件發佈訂閱就完成了,後面不管如何擴展,咱們只須要添加相應的事件訂閱者便可。

相關文章
相關標籤/搜索