zoukankan      html  css  js  c++  java
  • 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,至于为什么不用解释了吧!

  • 相关阅读:
    codeforce1214E Petya and Construction Set
    codeforces1214D Treasure Island
    CCPC2019网络赛1002 array (主席树)
    POJ2442
    计算机网络-应用层(3)Email应用
    计算机网络-应用层(2)FTP协议
    计算机网络-应用层(1)Web应用与HTTP协议
    算法-排序(1)k路平衡归并与败者树
    算法-搜索(6)B树
    RSA加密算法和SSH远程连接服务器
  • 原文地址:https://www.cnblogs.com/ll409546297/p/10102456.html
Copyright © 2011-2022 走看看