spring中事件、监听器详解
监听器的实现实质上就是观察者模式,本文主要从应用上下文事件ApplicationContextEvent来了解spring中监听器的使用。
ApplicationContextEvent事件有哪些
首先,我们看下spring中应用上下文的事件有哪些?
何时注册的事件
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
在容器创建过程中,有一个容器启动refresh()方法
public AnnotationConfigApplicationContext(Class... componentClasses) {
this();
this.register(componentClasses);
this.refresh();
}
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
//初始化事件多播器,作用就是广播事件
this.initApplicationEventMulticaster();
this.onRefresh();
//注册监听器到多播器中
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
//在完成刷新的方法中会发布事件
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
何时发布的事件
以容器刷新事件为例:
容器完成刷新的方法,发布事件 ContextRefreshedEvent
protected void finishRefresh() {
this.clearResourceCaches();
this.initLifecycleProcessor();
this.getLifecycleProcessor().onRefresh();
//发布上下文刷新事件
this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
LiveBeansView.registerApplicationContext(this);
}
调用容器close()方法时会发送上下文关闭事件
protected void doClose() {
if (this.active.get() && this.closed.compareAndSet(false, true)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Closing " + this);
}
LiveBeansView.unregisterApplicationContext(this);
try {
this.publishEvent((ApplicationEvent)(new ContextClosedEvent(this)));
} catch (Throwable var3) {
this.logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", var3);
}
if (this.lifecycleProcessor != null) {
try {
this.lifecycleProcessor.onClose();
} catch (Throwable var2) {
this.logger.warn("Exception thrown from LifecycleProcessor on context close", var2);
}
}
this.destroyBeans();
this.closeBeanFactory();
this.onClose();
if (this.earlyApplicationListeners != null) {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
this.active.set(false);
}
}
在调用发布事件的方法中,会使用多播器获取到事件的列表,调用监听器执行相应的逻辑
public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);
Executor executor = this.getTaskExecutor();
Iterator var5 = this.getApplicationListeners(event, type).iterator();
while(var5.hasNext()) {
ApplicationListener<?> listener = (ApplicationListener)var5.next();
//如果执行器不为空,异步执行
if (executor != null) {
executor.execute(() -> {
//方法中会调用监听器的onApplicationEvent()方法
this.invokeListener(listener, event);
});
} else {
this.invokeListener(listener, event);
}
}
}
自定义监听器的实现
自定义事件
public class MyEvent extends ApplicationEvent {
public String getEventName() {
return eventName;
}
private String eventName;
public MyEvent(Object source, String eventName) {
super(source);
this.eventName = eventName;
}
}
事件监听器
public class MyEventListener implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent myEvent) {
System.out.println("发布了事件,监听器"+myEvent.getEventName()+"做出响应");
}
}
测试类
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
MyEventListener myEventListener = new MyEventListener();
applicationContext.addApplicationListener(myEventListener);
// 启动上下文
applicationContext.refresh();
// 发布事件
applicationContext.publishEvent(new MyEvent("object","自定义测试"));
applicationContext.close();
}
测试结果