天天看點

ApplicationEventPublisher的簡單使用

從需求開始

一個簡單的場景,就是使用者注冊成功後,發短信通知和發郵件通知,其實這樣的場景就是兩種處理情況

  1. 注冊成功後起一個線程執行發短信和發郵件通知
  2. 發送使用者ID到mq,然後mq去執行

也許還有其他,那就是我的知識盲區了。其實如果正規的話這種耗時的操作應該是使用MQ,但是使用MQ其實無形之間就增加了系統的複雜性,那麼此時可以使用ApplicationEventPublisher代替MQ

源碼下載下傳

​​ChaiRongD/Demooo - Gitee.com​​

代碼:注冊使用者然後發短信這樣的場景

controller

@GetMapping("/insert")
    public Object insertMessage(){

        //注冊使用者
        Student student=new Student();
        student.setId(1);
        student.setName(LocalDateTime.now().toString());

        eventPublisher.publishEvent(new StudentEvent(this,student));

        return 1;


    }      

事件類 

@Getter
public class StudentEvent extends ApplicationEvent {


    private Student student;

    public StudentEvent(Object source,Student student) {
        super(source);
        this.student = student;
    }
}      

實體類 

@Data
public class Student {


    private Integer id;
    private String name;
}      

處理類 

@Component
public class EventHandleListener {




    @EventListener
    public void handleEvent(StudentEvent studentEvent) throws Exception {

        System.out.println("哒哒哒");
        System.out.println("哒哒哒");
        System.out.println("哒哒哒");
        System.out.println(studentEvent.getStudent());
    }

}      

源碼分析:為什麼能走到自定義的EventHandleLister

其實就是下面的一行代碼,跟一下就行

eventPublisher.publishEvent(new StudentEvent(this,student));      

 一直跟就到了AbstractApplicationContext

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
    Assert.notNull(event, "Event must not be null");

    // 省略

    // Multicast right now if possible - or lazily once the multicaster is initialized
    if (this.earlyApplicationEvents != null) {
      this.earlyApplicationEvents.add(applicationEvent);
    }
    else {
            //擷取多點傳播器,然後執行派發,跟此處的multicastEvent方法
      getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
    }

    // 省略
    
  }      
//SimpleApplicationEventMulticaster
@Override
  public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    Executor executor = getTaskExecutor();
    for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
      if (executor != null) {
        executor.execute(() -> invokeListener(listener, event));
      }
      else {
        invokeListener(listener, event);
      }
    }
  }      

參考