spring源碼-事件&監聽3.6

  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,至於爲何不用解釋了吧!

相關文章
相關標籤/搜索