从需求开始
一个简单的场景,就是用户注册成功后,发短信通知和发邮件通知,其实这样的场景就是两种处理情况
- 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); } } }
网络异常,图片无法展示
|
在往下就是method.invoke执行反射调用了,就进入了欧盟自定义的事件处理器