从需求开始
一个简单的场景,就是用户注册成功后,发短信通知和发邮件通知,其实这样的场景就是两种处理情况
- 注册成功后起一个线程执行发短信和发邮件通知
- 发送用户ID到mq,然后mq去执行
也许还有其他,那就是我的知识盲区了。其实如果正规的话这种耗时的操作应该是使用MQ,但是使用MQ其实无形之间就增加了系统的复杂性,那么此时可以使用ApplicationEventPublisher代替MQ
源码下载
ChaiRongD/Demooo - Gitee.com
代码:注册用户然后发短信这样的场景
controller
代码语言:javascript复制@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;
}
事件类
代码语言:javascript复制@Getter
public class StudentEvent extends ApplicationEvent {
private Student student;
public StudentEvent(Object source,Student student) {
super(source);
this.student = student;
}
}
实体类
代码语言:javascript复制@Data
public class Student {
private Integer id;
private String name;
}
处理类
代码语言:javascript复制@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
其实就是下面的一行代码,跟一下就行
代码语言:javascript复制eventPublisher.publishEvent(new StudentEvent(this,student));
一直跟就到了AbstractApplicationContext
代码语言:javascript复制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);
}
// 省略
}
代码语言:javascript复制//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执行反射调用了,就进入了欧盟自定义的事件处理器
参考
多线程在Spring中的使用_CBeann的博客-CSDN博客