介绍

@EventListener 是 Spring 框架中用于监听并处理 应用事件(ApplicationEvent) 的注解,它是 Spring 事件机制的核心之一。通过 @EventListener,你可以轻松地在应用中实现 事件驱动编程(Event-Driven Programming),实现模块之间的 解耦通信。

创建Event事件

事件是一个继承自 ApplicationEvent 的类,用于封装需要传递的数据。

package com.fastjs.demo.event;

import org.springframework.context.ApplicationEvent;

public class CustomEvent extends ApplicationEvent {
    public CustomEvent(Object source) {
        super(source);
    }

    @Override
    public String toString() {
        return "My Custom Event";
    }
}

创建Publisher发布

通过注入 ApplicationEventPublisher 来发布事件。

package com.fastjs.demo.publisher;

import com.fastjs.demo.event.CustomEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

import java.util.HashMap;

@Component
public class CustomEventPublisher {

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    public void publishCustomEvent(final String message) {
        HashMap<String, String> map = new HashMap<>();
        map.put("name", "张三");
        map.put("age", "20");
        System.out.println("Publishing custom event. " + message);
        CustomEvent customEvent = new CustomEvent(map);
        applicationEventPublisher.publishEvent(customEvent);
    }
}

创建Listener监听

使用 @EventListener 注解的方法会监听特定事件。

package com.fastjs.demo.listener;

import cn.hutool.json.JSONUtil;
import com.fastjs.demo.event.CustomEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
public class CustomEventListener {

    @Order(1)
    @EventListener
    public void handleCustomEvent(CustomEvent event) {
        Object object = event.getSource();
        System.out.println(JSONUtil.toJsonStr(object));
        System.out.println("1 - Received spring boot custom event - " + event.toString());
    }

    @Order(2)
    @EventListener
    public void handleCustomEvent2(CustomEvent event) {
        Object object = event.getSource();
        System.out.println(JSONUtil.toJsonStr(object));
        System.out.println("2 - Received spring boot custom event - " + event.toString());
    }
}

测试用例验证

@RestController
public class TestEventController {

    @Autowired
    private CustomEventPublisher customEventPublisher;

    @GetMapping("/testEvent")
    public String testEvent() {
        customEventPublisher.publishCustomEvent("测试事件");
        return "success";
    }

}

【输出日志】

Publishing custom event. 测试事件
{"name":"张三","age":"20"}
1 - Received spring boot custom event - My Custom Event
{"name":"张三","age":"20"}
2 - Received spring boot custom event - My Custom Event

拓展

  • 如果你希望监听器在主事务完成后执行,务必使用 @TransactionalEventListener,这样才能保证主任务完成后再执行监听逻辑。

  • 如果需要异步执行,通过@Async + @TransactionalEventListener

  • 如果同一个事件,有多个监听,需要保证顺序,请使用 @Order 控制执行顺序