一、什么是Spring中的事件监听机制?
Spring框架中的事件监听机制是一种设计模式,它允许你定义和触发事件,同时允许其他组件监听这些事件并在事件发生时作出响应。这种机制基于观察者模式,提供了一种松耦合的方式来实现组件间的通信。
二、Spring事件监听机制的关键概念
1. 事件(Event)
事件是应用程序中的一个信号,表明某个动作已经发生或某个条件已经满足。在Spring中,事件通常是实现ApplicationEvent接口的类来表示的。Spring为我们提供了多种内置的事件类型,如ContextStartedEvent、ContextRefreshedEvent,ContextCloseEvent、ContextStoppedEvent等事件,分别对应于应用程序上下文的不同生命周期阶段。当然我们也可以自定义自己的事件类型,即:通过实现ApplicationEvent接口或扩展ApplicationEvent类。
2. 事件发布者(Event Publisher)
事件发布者负责将事件发布出去,然后通过Spring的智能事件派发,把发布的事件派发给对应该事件类型的所有监听器。在Spring中,ApplicationContext自身就是一个事件发布者(因为ApplicationContext接口继承了ApplicationEventPublisher接口),它可以发布应用程序事件(比如ContextRefreshedEvent ,ContextCloseEvent等事件)。【通常我们会让自定义组件实现 ApplicationEventPublisherAware接口,然后实现接口中的如下方法把事件发布者对象注入到组件中】
@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.applicationEventPublisher = applicationEventPublisher;}
3. 事件监听器(Event Listener)
事件监听器是实现ApplicationListener接口的组件,它们可以监听和响应事件。监听器需要实现onApplicationEvent方法,以便在接收到事件时进行处理。此外,Spring给我们提供了一个 @EventListener注解,允许你直接在方法上标注以监听特定类型的事件。当事件发生时,Spring会自动调用这些方法。(注意:事件监听器一定要放入IOC容器中才会生效。)
4. 事件传播
事件可以在不同的Spring容器之间传播,例如从子容器传播到父容器。
5. 同步与异步事件
Spring支持同步和异步事件处理。
三、实现一个简单的事件监听功能
需求描述: 程序中有一个添加用户的业务组件,要求当用户添加成功时,发布一个添加用户成功事件,然后通过添加用户成功事件的监听器给管理员发送一封邮件。
1. 业务组件
package com.shg.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.shg.beans.User;public interface UserService extends IService<User> {User addUser(User user);
}
package com.shg.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shg.beans.User;
import com.shg.listener.event.UserAddSuccessEvent;
import com.shg.mapper.UserMapper;
import com.shg.service.UserService;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService, ApplicationEventPublisherAware {private ApplicationEventPublisher applicationEventPublisher;private final UserMapper userMapper;public UserServiceImpl(UserMapper userMapper) {this.userMapper = userMapper;}@Overridepublic User addUser(User user) {userMapper.insert(user);applicationEventPublisher.publishEvent(new UserAddSuccessEvent(this, user));return user;}@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.applicationEventPublisher = applicationEventPublisher;}
}
2. 添加用户成功事件
package com.shg.listener.event;import com.shg.beans.User;
import org.springframework.context.ApplicationEvent;public class UserAddSuccessEvent extends ApplicationEvent {private final User user;public UserAddSuccessEvent(Object source, User user) {super(source);this.user = user;}public User getUser() {return user;}
}
3. 添加用户成功事件监听器
package com.shg.listener;import com.shg.listener.event.UserAddFailEvent;
import com.shg.listener.event.UserAddSuccessEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;// 实现ApplicationListener接口的方式
// @Slf4j
// @Component
// public class UserAddListener implements ApplicationListener<UserAddSuccessEvent> {
// @Override
// public void onApplicationEvent(UserAddSuccessEvent event) {
// log.info("创建用户:{}, 成功,已发送短信给管理员...", event.getUser());
// }
// }// 使用@EventListener的方式
@Slf4j
@Component
public class UserAddListener {@EventListener(value = {UserAddSuccessEvent.class})public void listenerUserAddSuccessEvent(UserAddSuccessEvent event) {log.info("创建用户:{}, 成功,已发送短信给管理员...", event.getUser());}
}