美文网首页
Spring 源码 - 事件监听

Spring 源码 - 事件监听

作者: 萌妈码码 | 来源:发表于2018-09-18 18:26 被阅读0次

    Spring中对事件的监听及处理是基于JDK的监听器实现的。在理解JDK的监听者实现之后,看这部分相关的源码会很清晰。

    1. Spring中的事件,抽象类ApplicationEvent继承自EventObject
    public abstract class ApplicationEvent extends EventObject {
        /**
         * Create a new ApplicationEvent.
         * @param source the object on which the event initially occurred (never {@code null})
         */
        public ApplicationEvent(Object source) {
            super(source);
            this.timestamp = System.currentTimeMillis();
        }
    }
    

    然后在其基础之上,定义了很多ApplicationEvent子类,对应各种不同阶段或者不同模块中的事件。比如:ApplicationContextEvent, ContextRefreshedEvent, SessionConnectedEvent等。

    1. Spring的ApplicationListener,也继承子JDK的EventListener
    public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
    
        /**
         * Handle an application event.
         * @param event the event to respond to
         */
        void onApplicationEvent(E event);
    
    }
    
    public interface EventListener {
    }
    

    在应用中,可以根据需要实现该监听器接口,制定需要监听的事件类型,覆写onApplicationEvent是现在具体需要做的操作。

    1. 监听者模式中的事件源。
      不同事件的事件源不同。以ApplicationContextEvent为例,它的事件源是ApplicationContext。那么顺藤摸瓜,一定是在ApplicationContext的某个方法中添加了监听器,并且在适当的地方调用了处理方法。
      ApplicationContext是个接口,对应的实现类有很多,在AbstractApplicationContext中,refresh()方法中,有注册监听器,并且在Refresh结束后,finishRefresh()方法中处理对应的事件。详细请看源码:
    public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                // Prepare this context for refreshing.
                prepareRefresh();
    
                // Tell the subclass to refresh the internal bean factory.
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
                // Prepare the bean factory for use in this context.
                prepareBeanFactory(beanFactory);
    
                try {
                    // Allows post-processing of the bean factory in context subclasses.
                    postProcessBeanFactory(beanFactory);
    
                    // Invoke factory processors registered as beans in the context.
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    // Register bean processors that intercept bean creation.
                    registerBeanPostProcessors(beanFactory);
    
                    // Initialize message source for this context.
                    initMessageSource();
    
                    // Initialize event multicaster for this context.
                    initApplicationEventMulticaster();
    
                    // Initialize other special beans in specific context subclasses.
                    onRefresh();
    
                    // Check for listener beans and register them.
                    registerListeners();
    
                    // Instantiate all remaining (non-lazy-init) singletons.
                    finishBeanFactoryInitialization(beanFactory);
    
                    // Last step: publish corresponding event.
                    finishRefresh();
                }
    
                catch (BeansException ex) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("Exception encountered during context initialization - " +
                                "cancelling refresh attempt: " + ex);
                    }
    
                    // Destroy already created singletons to avoid dangling resources.
                    destroyBeans();
    
                    // Reset 'active' flag.
                    cancelRefresh(ex);
    
                    // Propagate exception to caller.
                    throw ex;
                }
    
                finally {
                    // Reset common introspection caches in Spring's core, since we
                    // might not ever need metadata for singleton beans anymore...
                    resetCommonCaches();
                }
            }
        }
    
        /**
         * Add beans that implement ApplicationListener as listeners.
         * Doesn't affect other listeners, which can be added without being beans.
         */
        protected void registerListeners() {
            // Register statically specified listeners first.
            for (ApplicationListener<?> listener : getApplicationListeners()) {
                getApplicationEventMulticaster().addApplicationListener(listener);
            }
    
            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let post-processors apply to them!
            String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
            for (String listenerBeanName : listenerBeanNames) {
                getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
            }
    
            // Publish early application events now that we finally have a multicaster...
            Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
            this.earlyApplicationEvents = null;
            if (earlyEventsToProcess != null) {
                for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                    getApplicationEventMulticaster().multicastEvent(earlyEvent);
                }
            }
        }
    
        @Override
        public void multicastEvent(ApplicationEvent event) {
            multicastEvent(event, resolveDefaultEventType(event));
        }
    
        @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);
                }
            }
        }
    

    从以上可以看出来,不管框架所做的事情有多复杂,其实也就是一些基本原理的应用。上面的一二三,其实分别对应了JDKEventObject, EventListener, 和Source

    相关文章

      网友评论

          本文标题:Spring 源码 - 事件监听

          本文链接:https://www.haomeiwen.com/subject/arhmnftx.html