美文网首页
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源码探究:事件机制

    结合Spring源码分析Spring事件机制 问题 问题描述:项目中配置事件监听,监听当容器加载完成之后,做一些初...

  • Spring 源码 - 事件监听

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

  • spring源码事件监听

    spring的事件监听机制,主要利用了监听者设计模式,那如何spring自带的事件和自定义的事件是如何触发监听器的...

  • 下单流程解耦新方案-你知道Spring事件监听机制吗

    一、Spring事件监听介绍 Spring对事件监听是通过事件类型、事件类型监听和事件发布器3个部分来完成的 上面...

  • Spring事件源码解析

    Spring事件监听源码分析 众所周知,在Spring中集成了内部的消息分发机制,可以在代码中使用注解@Event...

  • Spring事件监听源码解析

    大家对ApplicationListener应该不会陌生,但是大家是否了解Spring事件监听机制是怎么实现的呢?...

  • Spring事件监听--源码总结

    Spring事件监听 1.举例 (1)定义监听器监听的对象BaseFetchDataEvent (2)创建一个测试...

  • 浅谈Spring事件监听

    浅谈Spring事件监听在谈Spring的事件监听之前,让我们先了解一下Spring容器,什么是Applicati...

  • Spring源码阅读----Spring事件监听机制

    概述 经过IoC的解析,我们需要将注意力再拉回到refresh方法中。我们还有这几个方法还没解析完: 这里继续,先...

  • Spring 应用启动事件

    监听Spring boot应用的事件只需实现ApplicationListener接口来监听对应事件. 有些事件实...

网友评论

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

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