一、什么是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());}
}