【springboot】ApplicationListener用法及源码
用法
方法一:继承ApplicationListener
- 传递事件
继承于ApplicationEvent
public class ForDebuggerEvent extends ApplicationEvent {public ForDebuggerEvent(Object source) {super(source);}public void executeEvent() {System.out.println("ForDebuggerEvent executeEvent");}}
- 监听器
public class ForDebuggerEventListener implements ApplicationListener<ForDebuggerEvent> {@Overridepublic void onApplicationEvent(ForDebuggerEvent event) {event.executeEvent();}
}
- 事件推送
SpringUtil.publishEvent(new ForDebuggerEvent(new HashMap<>()));
方法二:@EventListener
- 传递事件
和方法一相同,继承于ApplicationEvent
public class ErrorLogEvent extends ApplicationEvent {public ErrorLogEvent(Object source) {super(source);}}
- 监听器
public class LogEventListener {@Async@Order@EventListener(ErrorLogEvent.class)public void errorLog(ErrorLogEvent event) {Object source = event.getSource();if(source instanceof ErrorLog){ErrorLog errorLog = (ErrorLog) source;log.info("[错误日志] => {}", JSON.toJSONString(errorLog));}}
}
- 事件推送
SpringUtil.publishEvent(new ErrorLogEvent(errorLog));
源码
方法一
SpringUtil.publishEvent
从SpringUtil出发,由于实现了ApplicationContextAware,可以获取到ApplicationContext
applicationContext.publishEvent
event为传递事件。获取到监听事件控制器,执行事件处理
getApplicationEventMulticaster().multicastEvent
通过event获取符合的ApplicationListener
getApplicationListeners
在这里判断event是否是被注册到IOC的Listener监听的对象,返回符合要求的Listener,这里匹配到两个,一个我们自定义,一个spring默认
。具体代码分析略
invokeListener => listener.onApplicationEvent回调
传递Listener,最终回调listener.onApplicationEvent(event);
方法二
与方法一的区别
整体执行逻辑和方法一相同,唯一的区别就是Listener由于我们没有继承ApplicationListener,而是通过注解。
当执行listener.onApplicationEvent时候,这里的Listener是通过适配器模式,创建的ApplicationListenerMethodAdapter对象
内部字段有我们自定义的Listener的beanName,method为监听的自定义方法
最终通过反射执行Method方法
完成注解自定义方法的回调