ApplicationEventPublisher的简单使用

2023-12-25 18:54:11 浏览数 (1)

从需求开始

一个简单的场景,就是用户注册成功后,发短信通知和发邮件通知,其实这样的场景就是两种处理情况

  1. 注册成功后起一个线程执行发短信和发邮件通知
  2. 发送用户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博客

0 人点赞