Spring 事件驱动编程初探:用 @EventListener 轻松处理业务通知

发布于:2025-08-30 ⋅ 阅读:(21) ⋅ 点赞:(0)

一、核心概念与模型

Spring 的事件机制是观察者模式(也叫发布-订阅模型)的一种典型实现。它主要由三个核心部分组成:

  1. 事件 (Event): 承载信息的对象,通常是某种状态变化的通知。可以是继承 ApplicationEvent 的类,也可以是任何普通的 Java 对象(POJO)。

  2. 发布者 (Publisher): 负责产生并发布事件的组件。它通过 ApplicationEventPublisher 来发布事件。

  3. 监听器 (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 {

    @Resource
    private 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 {

    @Override
    public boolean isSupportedCourseEvent(Object event) {
        return event instanceof CourseEventDTO;
    }

    @Override
    public void handlerCourseEvent(Object courseEvent) {
        CourseEventDTO courseEventDTO = (CourseEventDTO) courseEvent;
        if (CollUtil.isEmpty(courseEventDTO.getCourseIds())) {
            return;
        }
        List<String> userIds = courseEventDTO.getUserIds();
        //处理逻辑
    }


网站公告

今日签到

点亮在社区的每一天
去签到