一、 什么是监听事件
在程序执行过程中对某一个功能或者事件进行监听。例如,用户登录成功后,发送短信或者邮件信息给用户。
二、如何完成监听事件
监听事件是基于观察者模式实现的,要完成监听事件,需要准备好,事件源、事件监听器和发布事件,实现上诉三个条件,就可以实现事件监听了。
三、监听事件实现
- 基于Spring 框架实现
事件源信息
import org.springframework.context.ApplicationEvent;
/**
* 基于Spring框架实现的事件监听
*
* 事件源,自定义一个事件源,具体的内容更具具体的业务进行实现。
*/
public class CustomEven extends ApplicationEvent {
public CustomEven(Object source) {
super(source);
}
}
事件监听器
/**
* 基于Spring框架实现的事件监听
*
* 事件监听器, 监听到指定的事件后,会触发的方法
*/
@Component
public class CustomListener implements ApplicationListener<CustomEven> {
/**
* 监听到事件触发后,执行的方法
* @param customEven
*/
@Override
public void onApplicationEvent(CustomEven customEven) {
System.out.println("==== 发送用户登录成功邮件 ==== ");
}
}
发布事件监听器
@RestController
public class TestController {
/**
* 基于 spring 的事件监听器,需要使用 applicationContext 进行发布处理
*/
@Autowired
private ApplicationContext applicationContext;
/**
* 基于Spring框架实现的事件监听
*/
@RequestMapping("/app/login")
public void login() {
System.out.println("==== 用户登录成功 ====");
System.out.println("--------------------------------");
// 事件源信息
CustomEven customEven = new CustomEven(this);
// 发布事件
applicationContext.publishEvent(customEven);
}
}
- 自定义实现
基础事件类
/**
* 自定义事件监听
* 自定义注解中 事件的父类,后面定义的事件类都要基础这个类
*/
public class ApplicationEven {
}
基础监听器类
/**
* 自定义事件监听器中
* 事件监听器接口
*/
public interface ApplicationListener<E extends ApplicationEven> {
void onEven(E e);
}
事件发布类,下面是不使用spring的框架进行监听器注册,基于spring框架的可以修改代码修改监听器的注册方式;
public class ListenerHandler {
private static List<ApplicationListener> listenerList;
/**
* 自定义使用该方法进行添加,如果配合 spring框架,可以不使用该方法,
* 直接使用 注解进行注册即可
* @param listener
*/
public static void addListener(ApplicationListener listener) {
listenerList.add(listener);
}
/**
* 进行事件的发布
* @param applicationEven
*/
public static void publishEvent(ApplicationEven applicationEven) {
for (ApplicationListener listener : listenerList) {
// 获取监听器中监听的事件
Class clazz = (Class)((ParameterizedType)listener.getClass().getGenericInterfaces()[0])
.getActualTypeArguments()[0];
// 事件相同时,触发监听方法
if (applicationEven.getClass().equals(clazz)) {
// 进行事件
listener.onEven(applicationEven);
}
}
}
}
事件源信息
public class CustomEven extends ApplicationEven {
public CustomEven() {
System.out.println("==== 自定义监听事件创建成功 ==== ");
}
}
事件监听器
@Component
public class CustomerListener implements ApplicationListener<CustomEven> {
@Override
public void onEven(CustomEven customEven) {
System.out.println("==== 发送用户登录成功邮件 ====");
}
}
发布事件监听器
@RestController
public class DocTestController {
@Autowired
private ListenerHandler listenerHandler;
@RequestMapping("/custom/login")
public void login() {
System.out.println("==== 用户登录成功 ====");
System.out.println("--------------------------------");
com.zt.study.demolistener.doc.custom.CustomEven even = new com.zt.study.demolistener.doc.custom.CustomEven();
listenerHandler.publishEvent(even);
}
}
- 基于aop使用注解实现
为什么需要使用注解实现,在原有业务已经实现的基础上,使用上述的两种方法,都要修改原来的业务代码,修改就可能导致出现bug,使用 注解的方式的话,就不需要修改原有的代码结构,只需要在需要增加事件监听的地方增加注解即可;
监听器注解
/**
* 自定义注解实现
* 根据具体的情况进行选择注解范围,当前选择的是方法上
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface Listener {
String value() default "";
}
AOP切面,切面中已经执行了事件的发布,事件源和事件监听器使用的是第一种方法中定义的。
@Component
@Aspect
public class ListenerAop {
private CustomEven even = new CustomEven(this);
@Autowired
private ApplicationContext applicationContext;
@Pointcut("@annotation(com.zt.study.demolistener.doc.anno.Listener)")
public void listenerPoint(){}
@Before(value = "listenerPoint()")
public void beforeLogin(JoinPoint joinPoint) {
System.out.println("---- 登录事件执行之前需要执行哪些 ----");
}
@After(value = "listenerPoint()")
public void afterlogin() {
System.out.println("---- 登录事件执行成功后 ----");
// 执行监听事件
applicationContext.publishEvent(even);
}
}
如何使用 自定义的监听器注解
@RestController
public class DocTestController {
@RequestMapping("/anno/login")
@Listener(value = "登录监听事件")
public void login() {
System.out.println("==== 用户登录成功 ====");
System.out.println("--------------------------------");
}
}