spring源码-事件&监听3.6
一、spring中的发布与监听模式,是我们最常用的一种观察者模式。spring在其中做了很多优化,目的就是让用户更好的使用事件与监听的过程。
二、常用的事件与监听中涉及到的接口和类为:ApplicationEvent、ApplicationListener、ApplicationEventPublisher或者ApplicationContext。ApplicationEventPublisher或者ApplicationContext其实使用的是同一个方法进行发布事件。
三、实现方式
参考:spring源码-Aware-3.4的第二类b点的实现方式,这里不详细解释。
四、源码部分
1)方法实现在:refresh()方法中的
this.initApplicationEventMulticaster();
this.registerListeners();
2)initApplicationEventMulticaster
protected void initApplicationEventMulticaster() { //获取本地的beanFactory ConfigurableListableBeanFactory beanFactory = this.getBeanFactory(); //判断是否自己加入applicationEventMulticaster的bean if (beanFactory.containsLocalBean("applicationEventMulticaster")) { //如果存在则赋值待用 this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class); if (this.logger.isDebugEnabled()) { this.logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } else { //如果没用,就直接使用默认的方式加入 this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); //加入容器,单例方式 beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster); if (this.logger.isDebugEnabled()) { this.logger.debug("Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [" + this.applicationEventMulticaster + "]"); } } }
可能有点奇怪,这个和事件以及监听有啥关系。后面为具体讲执行过程,留个悬念
3)registerListeners
protected void registerListeners() { //获取已有监听 Iterator var2 = this.getApplicationListeners().iterator(); //如果存在着添加到缓存中灯带执行 while(var2.hasNext()) { ApplicationListener listener = (ApplicationListener)var2.next(); this.getApplicationEventMulticaster().addApplicationListener(listener); } //获取ApplicationListener类型的beanNames String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false); String[] var5 = listenerBeanNames; int var4 = listenerBeanNames.length; //同样添加到具体的缓存中 for(int var3 = 0; var3 < var4; ++var3) { String lisName = var5[var3]; this.getApplicationEventMulticaster().addApplicationListenerBean(lisName); } } //添加到缓存中 //ListenerRetriever public void addApplicationListener(ApplicationListener listener) { //这里不详解释,有兴趣可以自己看一下源码,这里就是默认加入缓存的一个过程 AbstractApplicationEventMulticaster.ListenerRetriever var2 = this.defaultRetriever; synchronized(this.defaultRetriever) { this.defaultRetriever.applicationListeners.add(listener); this.retrieverCache.clear(); } } //添加到缓存中 public void addApplicationListenerBean(String listenerBeanName) { AbstractApplicationEventMulticaster.ListenerRetriever var2 = this.defaultRetriever; synchronized(this.defaultRetriever) { this.defaultRetriever.applicationListenerBeans.add(listenerBeanName); this.retrieverCache.clear(); } } //set数据,不详解释 private class ListenerRetriever { public final Set<ApplicationListener> applicationListeners = new LinkedHashSet(); public final Set<String> applicationListenerBeans = new LinkedHashSet(); private final boolean preFiltered; public ListenerRetriever(boolean preFiltered) { this.preFiltered = preFiltered; } //具体的获取监听的过程 public Collection<ApplicationListener> getApplicationListeners() { LinkedList<ApplicationListener> allListeners = new LinkedList(); Iterator var3 = this.applicationListeners.iterator(); while(var3.hasNext()) { ApplicationListener listener = (ApplicationListener)var3.next(); allListeners.add(listener); } if (!this.applicationListenerBeans.isEmpty()) { BeanFactory beanFactory = AbstractApplicationEventMulticaster.this.getBeanFactory(); Iterator var4 = this.applicationListenerBeans.iterator(); label23: while(true) { ApplicationListener listenerx; do { if (!var4.hasNext()) { break label23; } String listenerBeanName = (String)var4.next(); //获取实例 listenerx = (ApplicationListener)beanFactory.getBean(listenerBeanName, ApplicationListener.class); } while(!this.preFiltered && allListeners.contains(listenerx)); allListeners.add(listenerx); } } OrderComparator.sort(allListeners); return allListeners; } }
4)这就是spring中的准备过程,下面就是执行过程了。(publisher为ApplicationEventPublisher,可以参考实现方式)
public void test() { publisher.publishEvent(new TestEvent(this, "test")); }
public void publishEvent(ApplicationEvent event) { Assert.notNull(event, "Event must not be null"); if (this.logger.isTraceEnabled()) { this.logger.trace("Publishing event in " + this.getDisplayName() + ": " + event); } //这也就是前面留下悬念的过程 this.getApplicationEventMulticaster().multicastEvent(event); if (this.parent != null) { this.parent.publishEvent(event); } }
看一下注册的ApplicationEventMulticaster
public void multicastEvent(final ApplicationEvent event) { //这里获取具体的事件所有关注的监听者 Iterator var3 = this.getApplicationListeners(event).iterator(); while(var3.hasNext()) { final ApplicationListener listener = (ApplicationListener)var3.next(); //这里如果过存在线程池。则通过线程池执行 Executor executor = this.getTaskExecutor(); if (executor != null) { executor.execute(new Runnable() { public void run() { listener.onApplicationEvent(event); } }); } else { //或者同步执行 listener.onApplicationEvent(event); } } }
这里就是具体执行过程了!
5)当然获取具体监听的实现过程还是可以学习一下的,主要是泛型的应用:getApplicationListeners
protected Collection<ApplicationListener> getApplicationListeners(ApplicationEvent event) { //获取实际的事件classType Class<? extends ApplicationEvent> eventType = event.getClass(); //发生地new TestEvent(this, "test")中的this Class sourceType = event.getSource().getClass(); //查看缓存key AbstractApplicationEventMulticaster.ListenerCacheKey cacheKey = new AbstractApplicationEventMulticaster.ListenerCacheKey(eventType, sourceType); AbstractApplicationEventMulticaster.ListenerRetriever retriever = (AbstractApplicationEventMulticaster.ListenerRetriever)this.retrieverCache.get(cacheKey); //如果存在则直接返回 if (retriever != null) { return retriever.getApplicationListeners(); } else { //没有则重新声明保存 retriever = new AbstractApplicationEventMulticaster.ListenerRetriever(true); LinkedList<ApplicationListener> allListeners = new LinkedList(); AbstractApplicationEventMulticaster.ListenerRetriever var7 = this.defaultRetriever; synchronized(this.defaultRetriever) { //查看已有的监听 Iterator var9 = this.defaultRetriever.applicationListeners.iterator(); //判断是否支持 while(var9.hasNext()) { ApplicationListener listener = (ApplicationListener)var9.next(); if (this.supportsEvent(listener, eventType, sourceType)) { retriever.applicationListeners.add(listener); allListeners.add(listener); } } //如果没有 if (!this.defaultRetriever.applicationListenerBeans.isEmpty()) { BeanFactory beanFactory = this.getBeanFactory(); //遍历默认的 Iterator var10 = this.defaultRetriever.applicationListenerBeans.iterator(); while(var10.hasNext()) { String listenerBeanName = (String)var10.next(); //获取加入容器的监听 ApplicationListener listener = (ApplicationListener)beanFactory.getBean(listenerBeanName, ApplicationListener.class); //判断是否支持 if (!allListeners.contains(listener) && this.supportsEvent(listener, eventType, sourceType)) { retriever.applicationListenerBeans.add(listenerBeanName); allListeners.add(listener); } } } //排序 OrderComparator.sort(allListeners); //加入缓存方便下次执行 this.retrieverCache.put(cacheKey, retriever); return allListeners; } } } //判断方式 protected boolean supportsEvent(ApplicationListener listener, Class<? extends ApplicationEvent> eventType, Class sourceType) { SmartApplicationListener smartListener = listener instanceof SmartApplicationListener ? (SmartApplicationListener)listener : new GenericApplicationListenerAdapter(listener); return ((SmartApplicationListener)smartListener).supportsEventType(eventType) && ((SmartApplicationListener)smartListener).supportsSourceType(sourceType); } //判断过程 public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) { Class typeArg = GenericTypeResolver.resolveTypeArgument(this.delegate.getClass(), ApplicationListener.class); if (typeArg == null || typeArg.equals(ApplicationEvent.class)) { Class targetClass = AopUtils.getTargetClass(this.delegate); if (targetClass != this.delegate.getClass()) { typeArg = GenericTypeResolver.resolveTypeArgument(targetClass, ApplicationListener.class); } } return typeArg == null || typeArg.isAssignableFrom(eventType); } public static Class<?> resolveTypeArgument(Class clazz, Class genericIfc) { Class[] typeArgs = resolveTypeArguments(clazz, genericIfc); if (typeArgs == null) { return null; } else if (typeArgs.length != 1) { throw new IllegalArgumentException("Expected 1 type argument on generic interface [" + genericIfc.getName() + "] but found " + typeArgs.length); } else { return typeArgs[0]; } } public static Class[] resolveTypeArguments(Class clazz, Class genericIfc) { return doResolveTypeArguments(clazz, clazz, genericIfc); } private static Class[] doResolveTypeArguments(Class ownerClass, Class classToIntrospect, Class genericIfc) { for(; classToIntrospect != null; classToIntrospect = classToIntrospect.getSuperclass()) { if (genericIfc.isInterface()) { Type[] ifcs = classToIntrospect.getGenericInterfaces(); Type[] var7 = ifcs; int var6 = ifcs.length; for(int var5 = 0; var5 < var6; ++var5) { Type ifc = var7[var5]; Class[] result = doResolveTypeArguments(ownerClass, ifc, genericIfc); if (result != null) { return result; } } } else { Class[] result = doResolveTypeArguments(ownerClass, classToIntrospect.getGenericSuperclass(), genericIfc); if (result != null) { return result; } } } return null; } private static Class[] doResolveTypeArguments(Class ownerClass, Type ifc, Class genericIfc) { if (ifc instanceof ParameterizedType) { ParameterizedType paramIfc = (ParameterizedType)ifc; Type rawType = paramIfc.getRawType(); if (genericIfc.equals(rawType)) { Type[] typeArgs = paramIfc.getActualTypeArguments(); Class[] result = new Class[typeArgs.length]; for(int i = 0; i < typeArgs.length; ++i) { Type arg = typeArgs[i]; result[i] = extractClass(ownerClass, arg); } return result; } if (genericIfc.isAssignableFrom((Class)rawType)) { return doResolveTypeArguments(ownerClass, (Class)rawType, genericIfc); } } else if (ifc != null && genericIfc.isAssignableFrom((Class)ifc)) { return doResolveTypeArguments(ownerClass, (Class)ifc, genericIfc); } return null; }
过程有点复杂,具体可以自己了解一下。大体方向就是通过获取接口的类型,然后具体的泛型类型,然后比对。
6)最后提一点,上面如果我们没有配置applicationEventMulticaster会导致一个问题就是同步问题。在initApplicationEventMulticaster中默认使用的是SimpleApplicationEventMulticaster的实例来实现具体过程。但是默认情况下是不会有线程池的方式加入的,所以这里需要重新注册名为applicationEventMulticaster的bean。具体实现方式为:
@Configuration public class PublisherConfiguration { @Bean public ThreadPoolTaskExecutor threadPoolTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(60); executor.setKeepAliveSeconds(60); executor.setQueueCapacity(3000); return executor; } /** * 事件监听会默认使用改监听器使用线程池执行 * @param executor * @return */ @Bean(name = "applicationEventMulticaster") public SimpleApplicationEventMulticaster simpleApplicationEventMulticaster(ThreadPoolTaskExecutor executor) { SimpleApplicationEventMulticaster applicationEventMulticaster = new SimpleApplicationEventMulticaster(); applicationEventMulticaster.setTaskExecutor(executor); return applicationEventMulticaster; } }
这里的名字必须为applicationEventMulticaster,至于为什么不用解释了吧!