@EventListener 是 Spring 框架提供的一个注解,用于在应用程序中注册事件监听器。它允许你在 Spring 管理的 Bean 中轻松地监听 Spring 的应用程序事件,并在事件发生时执行相应的处理逻辑。
Spring 的事件机制是一种松耦合的通信方式,它允许不同组件之间通过事件的发布和监听进行交互,而无需直接依赖彼此。这样可以提高系统的可维护性和可扩展性。
首先,需要定义一个事件类,这个类通常继承自ApplicationEvent。例如:
import org.springframework.context.ApplicationEvent; public class CustomEvent extends ApplicationEvent { private String message; public CustomEvent(Object source, String message) { super(source); this.message = message; } public String getMessage() { return message; } }
使用 ApplicationEventPublisher 来发布事件。可以通过在 Spring 的 Bean 中注入ApplicationEventPublisher,并调用其 publishEvent 方法来实现。例如:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Component; @Component public class EventPublisher { @Autowired private ApplicationEventPublisher eventPublisher; public void publishCustomEvent(String message) { CustomEvent customEvent = new CustomEvent(this, message); eventPublisher.publishEvent(customEvent); } }
在另一个 Spring Bean 中,使用@EventListener注解来监听CustomEvent。例如:
import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; @Component public class EventListenerBean { @EventListener public void handleCustomEvent(CustomEvent customEvent) { System.out.println("Received Custom Event: " + customEvent.getMessage()); } }
当使用 @EventListener 注解标记一个方法时,Spring 会在容器启动时扫描并注册该方法作为一个事件监听器。这个方法会被添加到一个内部的监听器列表中。
当 ApplicationEventPublisher 发布一个事件时,Spring 会遍历其内部的监听器列表,找到与该事件类型匹配的监听器方法(即方法参数类型匹配事件类型)。
对于 CustomEvent,当 EventPublisher 发布该事件时,Spring 会调用 EventListenerBean 中带有 @EventListener 注解且参数为 CustomEvent 的方法,执行相应的处理逻辑。
单一事件参数:通常,处理方法的参数是要监听的事件类型,如上述的 handleCustomEvent(CustomEvent customEvent),参数为 CustomEvent。
使用条件表达式:可以使用 condition 属性对事件进行筛选,只在满足条件时执行处理逻辑。例如:
@EventListener(condition = "#event.message.startsWith('Hello')") public void handleEventWithCondition(CustomEvent event) { System.out.println("Received event with message starting with Hello: " + event.getMessage()); }
这里的 condition 属性使用了 Spring 表达式语言(SpEL),只有当事件消息以 Hello 开头时,该处理方法才会被调用。
可以将@EventListener注解与@Async注解结合使用,使事件处理方法在一个单独的线程中异步执行。例如:
import org.springframework.scheduling.annotation.Async; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; @Component public class AsyncEventListenerBean { @Async @EventListener public void handleCustomEventAsync(CustomEvent customEvent) { System.out.println("Received Custom Event Asynchronously: " + customEvent.getMessage()); } }
这样,事件处理逻辑将在一个单独的线程池中异步执行,不会阻塞主线程,适用于处理耗时较长的事件处理任务。
如果一个事件监听器监听的是一个父类事件,它也会收到子类事件。例如,如果有一个 BaseEvent 类和一个 ChildEvent 类继承自 BaseEvent,并且有一个监听器监听 BaseEvent:
import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; @Component public class BaseEventListener { @EventListener public void handleBaseEvent(BaseEvent baseEvent) { System.out.println("Received Base Event: " + baseEvent.getClass()); } }
当发布 ChildEven t时,该监听器也会被触发,因为 ChildEvent 是 BaseEvent 的子类。
在 Spring Boot 应用中,@EventListener 可以用于各种场景,例如监听应用程序的启动事件 ApplicationStartedEvent 或 ApplicationReadyEvent,以在应用程序启动或准备好后执行一些初始化或后续操作。例如:
import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; @Component public class ApplicationStartListener { @EventListener public void onApplicationStarted(ApplicationStartedEvent event) { System.out.println("Application has started."); } }
也可以监听与配置文件加载、环境变更等相关的事件,根据不同的事件执行相应的逻辑,帮助实现更灵活的应用程序启动流程和状态管理。
使用@EventListener可以帮助你在 Spring 应用中实现松耦合的事件驱动架构,提高系统的可维护性和可扩展性,同时也为不同组件之间的通信和协作提供了一种简洁有效的方式。