spring中的ApplicationListener是一个监听器,用来监听容器中发布的事件
监听器也是一种观察者设计模式,该接口有一个onApplicationEvent()方法,
在事件发布时,此方法将会调用,实现监听的功能。
/** * Interface to be implemented by application event listeners. * Based on the standard {@code java.util.EventListener} interface * for the Observer design pattern. * * <p>As of Spring 3.0, an ApplicationListener can generically declare the event type * that it is interested in. When registered with a Spring ApplicationContext, events * will be filtered accordingly, with the listener getting invoked for matching event * objects only. * * @author Rod Johnson * @author Juergen Hoeller * @param <E> the specific ApplicationEvent subclass to listen to * @see org.springframework.context.event.ApplicationEventMulticaster */ public interface ApplicationListener<E extends ApplicationEvent> extends EventListener { /** * Handle an application event. * @param event the event to respond to */ void onApplicationEvent(E event); }
自定义一个实现了ApplicationListener接口的实现类MyEventListener:
@Component public class MyEventListener implements ApplicationListener<ApplicationEvent>{ @Override public void onApplicationEvent(ApplicationEvent event) { System.out.println("监听到的事件发布。。。。。。。。。。"+event); } }
配置类:
@Configuration @Import({MyEventListener.class}) public class ExtConfig { }
测试类:
public class ExtTest { @Test public void test(){ AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class); applicationContext.publishEvent(new ApplicationEvent(new String("我发布的事件")) {}); applicationContext.close(); } }
打印结果:可以看到监听到了容器中三个事件的发布
监听到的事件发布。。。。。。。。。。org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@3339ad8e: org.springframework.context.annotation.AnnotationConfigApplicationContext doClose 监听到的事件发布。。。。。。。。。。ExtTest$1[source=我发布的事件] 信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@3339ad8e: 监听到的事件发布。。。。。。。。。。org.springframework.context.event.ContextClosedE
发布流程:
refresh()--》finishRefresh()--》publishEvent(new ContextRefreshedEvent(this));
protected void publishEvent(Object event, ResolvableType eventType) { Assert.notNull(event, "Event must not be null"); if (logger.isTraceEnabled()) { logger.trace("Publishing event in " + getDisplayName() + ": " + event); } // Decorate event as an ApplicationEvent if necessary ApplicationEvent applicationEvent; if (event instanceof ApplicationEvent) { applicationEvent = (ApplicationEvent) event; } else { applicationEvent = new PayloadApplicationEvent<Object>(this, event); if (eventType == null) { eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType(); } } // Multicast right now if possible - or lazily once the multicaster is initialized if (this.earlyApplicationEvents != null) { this.earlyApplicationEvents.add(applicationEvent); } else { getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType); } // Publish event via parent context as well... if (this.parent != null) { if (this.parent instanceof AbstractApplicationContext) { ((AbstractApplicationContext) this.parent).publishEvent(event, eventType); } else { this.parent.publishEvent(event); } } }
执行getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);获取多波器(派发器)
multicastEvent(applicationEvent, eventType):
@Override public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) { ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
//获取到所有的监听器,并遍历循环 for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
//获取执行器,并判断,有,异步执行
Executor executor = getTaskExecutor(); if (executor != null) { executor.execute(new Runnable() { @Override public void run() { invokeListener(listener, event); } }); }
//没有就同步执行 else { invokeListener(listener, event); } } }
执行:doInvokeListener(listener, event)--》listener.onApplicationEvent(event);
@SuppressWarnings({"unchecked", "rawtypes"}) private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) { try { listener.onApplicationEvent(event); } catch (ClassCastException ex) { String msg = ex.getMessage(); if (msg == null || msg.startsWith(event.getClass().getName())) { // Possibly a lambda-defined listener which we could not resolve the generic event type for Log logger = LogFactory.getLog(getClass()); if (logger.isDebugEnabled()) { logger.debug("Non-matching event type for listener: " + listener, ex); } } else { throw ex; } } }
最终会去调用具体的onApplicationEvent()方法;