参考文章:https://blog.csdn.net/weixin_46228112/article/details/124644633
1、事件对象
表示所有事件的父类,内部有个source字段,表示事件源;我们自定义的事件需要继承这个类。
/**
* 事件对象
*/
public abstract class AbstractEvent {
//事件源
protected Object source;
public AbstractEvent(Object source) {
this.source = source;
}
public Object getSource() {
return source;
}
public void setSource(Object source) {
this.source = source;
}
}
2、事件监听器
我们使用一个接口来表示事件监听器,是个泛型接口,后面的类型E表示当前监听器需要监听的事件类型,此接口中只有一个方法,用来实现处理事件的业务;
/**
* 事件监听器
*
* @param 当前监听器感兴趣的事件类型
*/
public interface EventListener<E extends AbstractEvent> {
/**
* 此方法负责处理事件
*
* @param event 要响应的事件对象
*/
void onEvent(E event);
}
3、事件广播器
/**
* 事件广播器:
* 1.负责事件监听器的管理(注册监听器&移除监听器,将事件和监听器关联起来)
* 2.负责事件的广播(将事件广播给所有的监听器,对该事件感兴趣的监听器会处理该事件)
*/
public interface EventMulticaster {
/**
* 广播事件给所有的监听器,对该事件感兴趣的监听器会处理该事件
*
* @param event
*/
void multicastEvent(AbstractEvent event);
/**
* 添加一个事件监听器(监听器中包含了监听器中能够处理的事件)
*
* @param listener 需要添加监听器
*/
void addEventListener(EventListener<?> listener);
/**
* 将事件监听器移除
*
* @param listener 需要移除的监听器
*/
void removeEventListener(EventListener<?> listener);
}
事件广播器的默认实现
/**
* 事件广播器简单实现
*/
public class SimpleEventMulticaster implements EventMulticaster {
private Map<Class<?>, List<EventListener>> listenerMap = new ConcurrentHashMap<>();
@Override
public void multicastEvent(AbstractEvent event) {
List<EventListener> eventListeners = this.listenerMap.get(event.getClass());
if (eventListeners != null) {
for (EventListener eventListener : eventListeners) {
eventListener.onEvent(event);
}
}
}
@Override
public void addEventListener(EventListener<?> listener) {
Class<?> eventType = this.getEventType(listener);
List<EventListener> eventListeners = this.listenerMap.get(eventType);
if (eventListeners == null) {
eventListeners = new ArrayList<>();
this.listenerMap.put(eventType, eventListeners);
}
eventListeners.add(listener);
}
@Override
public void removeEventListener(EventListener<?> listener) {
Class<?> eventType = this.getEventType(listener);
List<EventListener> eventListeners = this.listenerMap.get(eventType);
if (eventListeners != null) {
eventListeners.remove(listener);
}
}
/**
* 获取事件监听器需要监听的事件类型
*
* @param listener
* @return
*/
protected Class<?> getEventType(EventListener listener) {
ParameterizedType parameterizedType = (ParameterizedType) listener.getClass().getGenericInterfaces()[0];
Type eventType = parameterizedType.getActualTypeArguments()[0];
return (Class<?>) eventType;
}
}
某个系统,当用户注册成功时,需要给用户发送邮件 + 优惠券
上面3个类支撑了整个事件模型,下面我们使用上面三个类来实现注册的功能
前提:springboot web
需要实现以下三个类:
1、自定义事件 - 用户注册成功事件
继承事件源抽象类
/**
* @Description: 用户注册成功事件
*/
public class UserRegisterSuccessEvent extends AbstractEvent {
private String name;
public UserRegisterSuccessEvent(Object source,String name) {
super(source);
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2、实现EventListener接口 - 用户注册成功监听
/**
* @author houChen
* @date 2022/8/24 23:51
* @Description:
*/
@Component
public class SendEmailOnUserRegisterListener implements EventListener<UserRegisterSuccessEvent> {
@Override
public void onEvent(UserRegisterSuccessEvent event) {
System.out.println(event.getName()+ "用户注册成功,开始发送邮件");
}
}
3、向spring容器中注入 事件广播器
@Configuration
public class config {
/**
* @Description: 将所有的事件监听器注册到事件广播器中
*/
@Bean
@Autowired(required = false)
public EventMulticaster eventMulticaster(List<EventListener> eventListeners) { //@1
EventMulticaster eventPublisher = new SimpleEventMulticaster();
if (eventListeners != null) {
eventListeners.forEach(eventPublisher::addEventListener);
}
return eventPublisher;
}
}
controller
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private EventMulticaster eventMulticaster;
@GetMapping("/register")
public void regisUser(@RequestParam("username") String username) {
System.out.println(username + ":注册成功");
UserRegisterSuccessEvent userRegisterSuccessEvent = new UserRegisterSuccessEvent(this, username);
eventMulticaster.multicastEvent(userRegisterSuccessEvent);
}
}
测试:访问接口 http://localhost:8080/test/register?username=houchen
如果注册成功,还需要发送优惠券的话,则 向spring容器中添加一个 注册成功发送优惠券的监听器即可
/**
* @author houChen
* @date 2022/8/24 23:51
* @Description:
*/
@Component
public class SendQuanOnUserRegisterListener implements EventListener<UserRegisterSuccessEvent> {
@Override
public void onEvent(UserRegisterSuccessEvent event) {
System.out.println(event.getName()+ "用户注册成功,开始发送优惠券");
}
}
发送上述请求
实际上事件机制采用的就是设计模式中的观察者模式,https://blog.csdn.net/hc1285653662/article/details/125381326
public class MyEvent extends ApplicationContextEvent {
private String describe;
public MyEvent(ApplicationContext source,String describe) {
super(source);
this.describe = describe;
}
public String getDescribe() {
return describe;
}
}
@Component
public class MyEventListenner {
@EventListener(value = {MyEvent.class})
public void myEventListenner(MyEvent myEvent) {
System.out.println("监听到了myEvent事件 ----> desp:" + myEvent.getDescribe());
}
}
@GetMapping("/test1")
public void test1() {
applicationContext.publishEvent(new MyEvent(applicationContext, "hello,我是houchenyayayya!!!"));
}