1、spring中的發佈與監聽模式,是咱們最經常使用的一種觀察者模式。spring在其中作了不少優化,目的就是讓用戶更好的使用事件與監聽的過程。html
2、經常使用的事件與監聽中涉及到的接口和類爲:ApplicationEvent、ApplicationListener、ApplicationEventPublisher或者ApplicationContext。ApplicationEventPublisher或者ApplicationContext其實使用的是同一個方法進行發佈事件。spring
3、實現方式緩存
參考:spring源碼-Aware-3.4的第二類b點的實現方式,這裏不詳細解釋。app
4、源碼部分學習
1)方法實如今:refresh()方法中的優化
this.initApplicationEventMulticaster();this
this.registerListeners();spa
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 + "]"); } } }
可能有點奇怪,這個和事件以及監聽有啥關係。後面爲具體講執行過程,留個懸念debug
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,至於爲何不用解釋了吧!