一、核心概念与模型
Spring 的事件机制是观察者模式(也叫发布-订阅模型)的一种典型实现。它主要由三个核心部分组成:
事件 (Event): 承载信息的对象,通常是某种状态变化的通知。可以是继承
ApplicationEvent
的类,也可以是任何普通的 Java 对象(POJO)。发布者 (Publisher): 负责产生并发布事件的组件。它通过
ApplicationEventPublisher
来发布事件。监听器 (Listener): 负责接收和处理事件的组件。它监听特定类型的事件并做出响应。
工作流程:发布者发布一个事件 -> Spring 的 ApplicationContext
(作为事件广播器)接收事件 -> 广播器将事件通知给所有注册的、对该事件感兴趣的监听器 -> 监听器执行自身的业务逻辑。
二、详细用法与步骤
我们将通过一个经典的业务场景——用户注册成功后,发送邮件和短信——来演示每一步的用法。
第 1 步:定义事件 (Event)
事件是一个简单的 POJO,用于封装需要传递的数据。自 Spring 4.2 以后,不再需要强制继承 ApplicationEvent
。
package jnpf.model.cultivate.event;import lombok.Getter;
import org.springframework.context.ApplicationEvent;@Getter
public class JnpfApplicationEvent<T> extends ApplicationEvent {private final T data;public JnpfApplicationEvent(T source) {super(source);this.data = source;}
}
第 2 步:发送消息
SpringContext.getApplicationContext().publishEvent(new JnpfApplicationEvent<>(CourseEventDTO.builder().courseIds(List.of(ftbCultivateCourseDTO.getCourseId())).userIds(new ArrayList<>()).whetherToChange(true).build()));
第 3 步:实现监听器 (Listener)
package jnpf.cultivate.event;import jnpf.model.cultivate.event.JnpfApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;/*** 事件处理程序** @author fantaibao* @date 2023/12/26*/
@Component
public class EventHandler {@Resourceprivate List<JnpfApplicationEventService> jnpfApplicationEventServices;@EventListener(value = JnpfApplicationEvent.class)public <T> void courseEvent(JnpfApplicationEvent<T> jnpfApplicationEvent) {Object data = jnpfApplicationEvent.getData();// 事件处理分发Optional<JnpfApplicationEventService> first = jnpfApplicationEventServices.stream().filter(t -> t.isSupportedCourseEvent(data)).findFirst();first.ifPresent(jnpfApplicationEventService -> jnpfApplicationEventService.handlerCourseEvent(data));}
}
第 4 步:创建事件处理类接口
package jnpf.cultivate.event;public interface JnpfApplicationEventService {/*** 是否支持此事件** @param event 事件* @return boolean*/boolean isSupportedCourseEvent(Object event);/*** 处理事件** @param courseEvent 事件入参*/void handlerCourseEvent(Object courseEvent);}
第 5 步:事件处理类impl
@Component
@RequiredArgsConstructor
public class JnpfApplicationEventCourseService implements JnpfApplicationEventService {@Overridepublic boolean isSupportedCourseEvent(Object event) {return event instanceof CourseEventDTO;}@Overridepublic void handlerCourseEvent(Object courseEvent) {CourseEventDTO courseEventDTO = (CourseEventDTO) courseEvent;if (CollUtil.isEmpty(courseEventDTO.getCourseIds())) {return;}List<String> userIds = courseEventDTO.getUserIds();//处理逻辑}