• spring源码分析系列 (15) 设计模式解析


     spring是目前使用最为广泛的Java框架之一。虽然spring最为核心是IOC和AOP,其中代码实现中很多设计模式得以应用,代码看起来简洁流畅,在日常的软件设计中很值得借鉴。以下是对一些设计模式的理解以及源码解析,希望能给大家对设计模式的理解有所帮助。

    1. 观察者模式:发布/订阅

    更多设计模式更新中.....

    (基于spring-4.3.23.RELEASE分析)  

    1、观察者模式: 发布/订阅

    如对观察者模式还不是很有概念,可以点击这里。spring中ApplicationEvent事件通知就是观察者模式的变种,巧妙的利用事件驱动机制实现容器刷新。开发者可充分利用该机制,实现框架的深度定制。下面分为几点展开:

    (a) spring中实现观察者模式的各个角色:

     ApplicationEventMulticaster是一个接口,定义了事件管理的基本行为,目前spring只有一个实现类和一个抽象类。这里先贴出定义理解各个角色的作用,后边一点点串联整个功能。

    public interface ApplicationEventMulticaster {
        /**
         * 增加一个具体事件监听器
         */
        void addApplicationListener(ApplicationListener<?> listener);
        /**
         * 增加一个事件监听器 以beanName形式 
         */
        void addApplicationListenerBean(String listenerBeanName);
        /**
         * 删除一个具体事件监听器
         */
        void removeApplicationListener(ApplicationListener<?> listener);
        /**
         * 删除一个事件监听器 以beanName形式 
         */
        void removeApplicationListenerBean(String listenerBeanName);
        /**
         * 删除所有事件监听器 
         */
        void removeAllListeners();
        /**
         * 发布事件
         */
        void multicastEvent(ApplicationEvent event);
        /**
         * 发布事件
         */
        void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);
    }

     ApplicationEvent是事件通知的媒介,也是消息传递的载体。这个类只是继承JDK原生的EventObject,约定为source的事件传递数据 只要理解其作用即可 比较简单所以贴出代码

    /**
     * Class to be extended by all application events. Abstract as it
     * doesn't make sense for generic events to be published directly.
     *
     * @author Rod Johnson
     * @author Juergen Hoeller
     */
    public abstract class ApplicationEvent extends EventObject {
    
        /** use serialVersionUID from Spring 1.2 for interoperability. */
        private static final long serialVersionUID = 7099057708183571937L;
    
        /** System time when the event happened. */
        private final long timestamp;
    
    
        /**
         * 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();
        }
    
    
        /**
         * Return the system time in milliseconds when the event happened.
         */
        public final long getTimestamp() {
            return this.timestamp;
        }
    
    }
    ApplicationEvent.java
    /**
     * <p>
     * The root class from which all event state objects shall be derived.
     * <p>
     * All Events are constructed with a reference to the object, the "source",
     * that is logically deemed to be the object upon which the Event in question
     * initially occurred upon.
     *
     * @since JDK1.1
     */
    
    public class EventObject implements java.io.Serializable {
    
        private static final long serialVersionUID = 5516075349620653480L;
    
        /**
         * The object on which the Event initially occurred.
         */
        protected transient Object  source;
    
        /**
         * Constructs a prototypical Event.
         *
         * @param    source    The object on which the Event initially occurred.
         * @exception  IllegalArgumentException  if source is null.
         */
        public EventObject(Object source) {
            if (source == null)
                throw new IllegalArgumentException("null source");
    
            this.source = source;
        }
    
        /**
         * The object on which the Event initially occurred.
         *
         * @return   The object on which the Event initially occurred.
         */
        public Object getSource() {
            return source;
        }
    
        /**
         * Returns a String representation of this EventObject.
         *
         * @return  A a String representation of this EventObject.
         */
        public String toString() {
            return getClass().getName() + "[source=" + source + "]";
        }
    }
    EventObject.java

    ApplicationEventPublisher是对外暴露发布事件接口的定义 ApplicationContext容器实现该接口定义:

    /**
     * Interface that encapsulates event publication functionality.
     * Serves as super-interface for {@link ApplicationContext}.
     *
     * @author Juergen Hoeller
     * @author Stephane Nicoll
     * @since 1.1.1
     * @see ApplicationContext
     * @see ApplicationEventPublisherAware
     * @see org.springframework.context.ApplicationEvent
     * @see org.springframework.context.event.EventPublicationInterceptor
     */
    public interface ApplicationEventPublisher {
    
        /**
         * Notify all <strong>matching</strong> listeners registered with this
         * application of an application event. Events may be framework events
         * (such as RequestHandledEvent) or application-specific events.
         * @param event the event to publish
         * @see org.springframework.web.context.support.RequestHandledEvent
         */
        void publishEvent(ApplicationEvent event);
    
        /**
         * Notify all <strong>matching</strong> listeners registered with this
         * application of an event.
         * <p>If the specified {@code event} is not an {@link ApplicationEvent},
         * it is wrapped in a {@link PayloadApplicationEvent}.
         * @param event the event to publish
         * @since 4.2
         * @see PayloadApplicationEvent
         */
        void publishEvent(Object event);
    
    }
    ApplicationEventPublisher.java

     SimpleApplicationEventMulticaster是AbstractApplicationEventMulticaster具体的实现,可以配置异步调用以解决效率问题以及事件调用异常的处理方式。主要的逻辑不复杂,很多实现的细节都隐藏在抽象类中,后续会有分析,很容易看得懂 接下来把目光聚集在AbstractApplicationEventMulticaster类。

     AbstractApplicationEventMulticaster抽象类是分析的重点,该类实现了大部分的核心功能,包括监听者增加、删除、根据发布的事件类型匹配监听者,下面将结合容器刷新来串联整个过程。

    (b) 容器刷新中使用到的事件机制。

    (1)、AbstractApplicationContext中refresh()是整个spring容器刷新的入口, 如果你看过spring源码肯定非常熟悉这段代码:

    @Override
    public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                // Prepare this context for refreshing.
                prepareRefresh();
    
                // 获取容器,具体实现类重载加载所有bean定义
                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();
    
                    // 初始化事件广播器 即上文的SimpleApplicationEventMulticaster 也可以重载该方法,注册自定义的广播器,实现定制化
                    initApplicationEventMulticaster();
    
                    // Initialize other special beans in specific context subclasses.
                    onRefresh();
    
                    // 开始注册监听器
                    registerListeners();
    
                    // Instantiate all remaining (non-lazy-init) singletons.
                    finishBeanFactoryInitialization(beanFactory);
    
                    // 完成最后容器工作 发布第一个容器刷新完成事件
                    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();
                }
            }
        }

     (2) 、跟踪initApplicationEventMulticaster()方法可以看出来,如果手动注入name为“applicationEventMulticaster”的bean 则spring会使用定制化的事件广播器,否则会默认使用SimpleApplicationEventMulticaster。

    /**
         * Name of the ApplicationEventMulticaster bean in the factory.
         * If none is supplied, a default SimpleApplicationEventMulticaster is used.
         * @see org.springframework.context.event.ApplicationEventMulticaster
         * @see org.springframework.context.event.SimpleApplicationEventMulticaster
         */
        public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
    
    
       /**
         * Initialize the ApplicationEventMulticaster.
         * Uses SimpleApplicationEventMulticaster if none defined in the context.
         * @see org.springframework.context.event.SimpleApplicationEventMulticaster
         */
        protected void initApplicationEventMulticaster() {
            ConfigurableListableBeanFactory beanFactory = getBeanFactory();
            if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
                this.applicationEventMulticaster =
                        beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
                if (logger.isTraceEnabled()) {
                    logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
                }
            }
            else {
                this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
                beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
                if (logger.isTraceEnabled()) {
                    logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
                            "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
                }
            }
        }
    initApplicationEventMulticaster()

     (3)、 此时事件广播器已经注册,再跟踪registerListeners()方法。 该方法主要完成所有监听者的注册、 触发最早起的事件通知,也是spring容器刷新阶段较早期触发的事件。

       /**
         * 注册所有的监听器 
         */
        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!
            // 获取所有监听器的bean name 并注册所有beanName 以待后续查找使用
            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);
                }
            }
        }

     (4)、跟踪AbstractApplicationEventMulticaster#addApplicationListener 和  AbstractApplicationEventMulticaster#addApplicationListenerBean。 两个方法都比较简单,都是往监听器持有者defaultRetriever注册。

    public abstract class AbstractApplicationEventMulticaster
            implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
        // 默认的监听器持有者 
        private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);
        // 使用缓存方式加快解析效率
        final Map<ListenerCacheKey, ListenerRetriever> retrieverCache =
                new ConcurrentHashMap<ListenerCacheKey, ListenerRetriever>(64);
    
        private ClassLoader beanClassLoader;
    
        private BeanFactory beanFactory;
    
        private Object retrievalMutex = this.defaultRetriever;
    
        //.........
    
        @Override
        public void addApplicationListener(ApplicationListener<?> listener) {
            synchronized (this.retrievalMutex) {
                // Explicitly remove target for a proxy, if registered already,
                // in order to avoid double invocations of the same listener.
                // 如果该类的代理类 需要将被代理类对象移除 防止产生两次通知的现象
                Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);
                if (singletonTarget instanceof ApplicationListener) {
                    this.defaultRetriever.applicationListeners.remove(singletonTarget);
                }
                this.defaultRetriever.applicationListeners.add(listener);
                this.retrieverCache.clear();
            }
        }
    
        @Override
        public void addApplicationListenerBean(String listenerBeanName) {
            synchronized (this.retrievalMutex) {
                this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
                this.retrieverCache.clear();
            }
        }
        
        //.........
    }
    View Code 

    (5)、再分析最关键的SimpleApplicationEventMulticaster#multicastEvent(final ApplicationEvent event, ResolvableType eventType) 根据发布的事件类别找到匹配的ApplicationListener集合,并触发通知。 串联了整个事件通知流程: 

    public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
        private Executor taskExecutor;
    
        private ErrorHandler errorHandler;
    
        // ..........
    
        @Override
        public void multicastEvent(ApplicationEvent event) {
            multicastEvent(event, resolveDefaultEventType(event));
        }
    
        @Override
        public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
            // 使用spring提供的ResolvableType类型解析类 匹配发布事件类型获得对应的监听器 
            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);
                }
            }
        }
    
        private ResolvableType resolveDefaultEventType(ApplicationEvent event) {
            return ResolvableType.forInstance(event);
        }
    
        protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
            ErrorHandler errorHandler = getErrorHandler();
            if (errorHandler != null) {
                try {
                    doInvokeListener(listener, event);
                }
                catch (Throwable err) {
                    errorHandler.handleError(err);
                }
            }
            else {
                doInvokeListener(listener, event);
            }
        }
    
        @SuppressWarnings({"unchecked", "rawtypes"})
        private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
            try {
                listener.onApplicationEvent(event);
            }
            catch (ClassCastException ex) {
                String msg = ex.getMessage();
                if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
                    // Possibly a lambda-defined listener which we could not resolve the generic event type for
                    // -> let's suppress the exception and just log a debug message.
                    Log logger = LogFactory.getLog(getClass());
                    if (logger.isDebugEnabled()) {
                        logger.debug("Non-matching event type for listener: " + listener, ex);
                    }
                }
                else {
                    throw ex;
                }
            }
        }
    
        private boolean matchesClassCastMessage(String classCastMessage, Class<?> eventClass) {
            // On Java 8, the message starts with the class name: "java.lang.String cannot be cast..."
            if (classCastMessage.startsWith(eventClass.getName())) {
                return true;
            }
            // On Java 11, the message starts with "class ..." a.k.a. Class.toString()
            if (classCastMessage.startsWith(eventClass.toString())) {
                return true;
            }
            // On Java 9, the message used to contain the module name: "java.base/java.lang.String cannot be cast..."
            int moduleSeparatorIndex = classCastMessage.indexOf('/');
            if (moduleSeparatorIndex != -1 && classCastMessage.startsWith(eventClass.getName(), moduleSeparatorIndex + 1)) {
                return true;
            }
            // Assuming an unrelated class cast failure...
            return false;
        }
    
    }
    View Code

    跟进AbstractApplicationEventMulticaster#getApplicationListeners(ApplicationEvent event, ResolvableType eventType)获取所有符合条件的监听器,涉及到spring的ResolvableType类型可以 点击这里 进行详细了解。

    public abstract class AbstractApplicationEventMulticaster
            implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
    
        private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);
        final Map<ListenerCacheKey, ListenerRetriever> retrieverCache =
                new ConcurrentHashMap<ListenerCacheKey, ListenerRetriever>(64);
        private ClassLoader beanClassLoader;
        private BeanFactory beanFactory;
        private Object retrievalMutex = this.defaultRetriever;
        
        // 。。。。。。。。。
    
        /**
         * 根据事件类型找到匹配的监听器集合 充分缓存机制解决效率问题
         *
         * Return a Collection of ApplicationListeners matching the given
         * event type. Non-matching listeners get excluded early.
         * @param event the event to be propagated. Allows for excluding
         * non-matching listeners early, based on cached matching information.
         * @param eventType the event type
         * @return a Collection of ApplicationListeners
         * @see org.springframework.context.ApplicationListener
         */
        protected Collection<ApplicationListener<?>> getApplicationListeners(
                ApplicationEvent event, ResolvableType eventType) {
    
            Object source = event.getSource();
            Class<?> sourceType = (source != null ? source.getClass() : null);
            ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
    
            // Quick check for existing entry on ConcurrentHashMap...
            ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
            if (retriever != null) {
                return retriever.getApplicationListeners();
            }
    
            if (this.beanClassLoader == null ||
                    (ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
                            (sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
                // Fully synchronized building and caching of a ListenerRetriever
                // 防止线程并发同步加载
                synchronized (this.retrievalMutex) {
                    retriever = this.retrieverCache.get(cacheKey);
                    // 再次检查 防止并发导致多次计算
                    if (retriever != null) {
                        return retriever.getApplicationListeners();
                    }
                    retriever = new ListenerRetriever(true);
                    Collection<ApplicationListener<?>> listeners =
                            retrieveApplicationListeners(eventType, sourceType, retriever);
                    this.retrieverCache.put(cacheKey, retriever);
                    return listeners;
                }
            }
            else {
                // No ListenerRetriever caching -> no synchronization necessary
                return retrieveApplicationListeners(eventType, sourceType, null);
            }
        }
    
        /**
         *  实际的事件类解析逻辑 结合上文提到的监听器持有者defaultRetriever  使用spring提供的ResolvableType类进行类型匹配
         *  最后找到符合条件的监听器
         * Actually retrieve the application listeners for the given event and source type.
         * @param eventType the event type
         * @param sourceType the event source type
         * @param retriever the ListenerRetriever, if supposed to populate one (for caching purposes)
         * @return the pre-filtered list of application listeners for the given event and source type
         */
        private Collection<ApplicationListener<?>> retrieveApplicationListeners(
                ResolvableType eventType, Class<?> sourceType, ListenerRetriever retriever) {
    
            List<ApplicationListener<?>> allListeners = new ArrayList<ApplicationListener<?>>();
            Set<ApplicationListener<?>> listeners;
            Set<String> listenerBeans;
            synchronized (this.retrievalMutex) {
                listeners = new LinkedHashSet<ApplicationListener<?>>(this.defaultRetriever.applicationListeners);
                listenerBeans = new LinkedHashSet<String>(this.defaultRetriever.applicationListenerBeans);
            }
            for (ApplicationListener<?> listener : listeners) {
                if (supportsEvent(listener, eventType, sourceType)) {
                    if (retriever != null) {
                        retriever.applicationListeners.add(listener);
                    }
                    allListeners.add(listener);
                }
            }
            if (!listenerBeans.isEmpty()) {
                BeanFactory beanFactory = getBeanFactory();
                for (String listenerBeanName : listenerBeans) {
                    try {
                        Class<?> listenerType = beanFactory.getType(listenerBeanName);
                        if (listenerType == null || supportsEvent(listenerType, eventType)) {
                            ApplicationListener<?> listener =
                                    beanFactory.getBean(listenerBeanName, ApplicationListener.class);
                            if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
                                if (retriever != null) {
                                    retriever.applicationListenerBeans.add(listenerBeanName);
                                }
                                allListeners.add(listener);
                            }
                        }
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        // Singleton listener instance (without backing bean definition) disappeared -
                        // probably in the middle of the destruction phase
                    }
                }
            }
            AnnotationAwareOrderComparator.sort(allListeners);
            return allListeners;
        }
    
        
        protected boolean supportsEvent(Class<?> listenerType, ResolvableType eventType) {
            if (GenericApplicationListener.class.isAssignableFrom(listenerType) ||
                    SmartApplicationListener.class.isAssignableFrom(listenerType)) {
                return true;
            }
            ResolvableType declaredEventType = GenericApplicationListenerAdapter.resolveDeclaredEventType(listenerType);
            return (declaredEventType == null || declaredEventType.isAssignableFrom(eventType));
        }
        
        protected boolean supportsEvent(ApplicationListener<?> listener, ResolvableType eventType, Class<?> sourceType) {
            GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
                    (GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
            return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
        }
    
    
        /**
         * Cache key for ListenerRetrievers, based on event type and source type.
         */
        private static final class ListenerCacheKey implements Comparable<ListenerCacheKey> {
    
            private final ResolvableType eventType;
    
            private final Class<?> sourceType;
    
            public ListenerCacheKey(ResolvableType eventType, Class<?> sourceType) {
                this.eventType = eventType;
                this.sourceType = sourceType;
            }
    
            // .......
        }
    
        /**
         * 监听器持有者 实际从bean容器获得监听器的bean实例 
         * Helper class that encapsulates a specific set of target listeners,
         * allowing for efficient retrieval of pre-filtered listeners.
         * <p>An instance of this helper gets cached per event type and source type.
         */
        private class ListenerRetriever {
    
            public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<ApplicationListener<?>>();
    
            public final Set<String> applicationListenerBeans = new LinkedHashSet<String>();
    
            private final boolean preFiltered;
    
            public ListenerRetriever(boolean preFiltered) {
                this.preFiltered = preFiltered;
            }
    
            public Collection<ApplicationListener<?>> getApplicationListeners() {
                List<ApplicationListener<?>> allListeners = new ArrayList<ApplicationListener<?>>(
                        this.applicationListeners.size() + this.applicationListenerBeans.size());
                allListeners.addAll(this.applicationListeners);
                if (!this.applicationListenerBeans.isEmpty()) {
                    BeanFactory beanFactory = getBeanFactory();
                    for (String listenerBeanName : this.applicationListenerBeans) {
                        try {
                            ApplicationListener<?> listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class);
                            if (this.preFiltered || !allListeners.contains(listener)) {
                                allListeners.add(listener);
                            }
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            // Singleton listener instance (without backing bean definition) disappeared -
                            // probably in the middle of the destruction phase
                        }
                    }
                }
                AnnotationAwareOrderComparator.sort(allListeners);
                return allListeners;
            }
        }
    
    }
    AbstractApplicationEventMulticaster.java

    (6)、最后finishRefresh()发布容器刷新成功事件

    /**
         * Finish the refresh of this context, invoking the LifecycleProcessor's
         * onRefresh() method and publishing the
         * {@link org.springframework.context.event.ContextRefreshedEvent}.
         */
        protected void finishRefresh() {
            // Initialize lifecycle processor for this context.
            initLifecycleProcessor();
    
            // Propagate refresh to lifecycle processor first.
            getLifecycleProcessor().onRefresh();
    
            // Publish the final event.
            // 发布容器刷新成功事件
            publishEvent(new ContextRefreshedEvent(this));
    
            // Participate in LiveBeansView MBean, if active.
            LiveBeansView.registerApplicationContext(this);
        }
    View Code

    (7)、跟踪上述的publishEvent(Object event, ResolvableType eventType)方法, spring容器实现了ApplicationEventPublisher接口 并委托事件广播器AbstractApplicationEventMulticaster完成事件到发布的过程。

        // 发布一个 ApplicationEvent 事件
        @Override
        public void publishEvent(ApplicationEvent event) {
            publishEvent(event, null);
        }
    
        // 发布一个ApplicationEvent事件 如果非ApplicationEvent类型事件,则默认被封装成PayloadApplicationEvent事件 传递实体
        @Override
        public void publishEvent(Object event) {
            publishEvent(event, null);
        }
    
        protected void publishEvent(Object event, ResolvableType eventType) {
            Assert.notNull(event, "Event must not be null");
            if (logger.isTraceEnabled()) {
                logger.trace("Publishing event in " + getDisplayName() + ": " + event);
            }
    
            // Decorate event as an ApplicationEvent if necessary
            // 如果非ApplicationEvent类型事件,则默认被封装成PayloadApplicationEvent事件 传递实体
            ApplicationEvent applicationEvent;
            if (event instanceof ApplicationEvent) {
                applicationEvent = (ApplicationEvent) event;
            }
            else {
                applicationEvent = new PayloadApplicationEvent<Object>(this, event);
                if (eventType == null) {
                    eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
                }
            }
    
            // Multicast right now if possible - or lazily once the multicaster is initialized
            if (this.earlyApplicationEvents != null) {
                this.earlyApplicationEvents.add(applicationEvent);
            }
            else {
                getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
            }
    
            // Publish event via parent context as well...
            // 如果存在父亲容器则在容器发布该事件
            if (this.parent != null) {
                if (this.parent instanceof AbstractApplicationContext) {
                    ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
                }
                else {
                    this.parent.publishEvent(event);
                }
            }
        }

    源码分析到这里基本串联了整个流程,用一张图说明容器刷新时候事件调用链图,展示整个过程的数据流:

     

    (c) 依据spring机制实现事件的发布/订阅 定制化框架。

    实际项目中会有一些定制化的需求,spring强大之处不仅仅是Bean的托管,还提供很多拓展机制,例如Bean生命周期各个的接口 点击这里了解更多,还有本文的主题ApplicationEvent发布特定的事件机制定制化框架。常见的spring内嵌Tomcat等Servlet容器提供Http服务 则优雅down机器很重要,需要等待所有业务请求处理完毕再关闭容器。 下面是一个简单的demo,也是拓展事件机制的基础:

     实际传递DTO

    @Data
    @AllArgsConstructor
    @ToString
    public class EventDto {
        private String name ;
    }

     发布的事件继承自 ApplicationEvent

    @Getter
    public class DemoApplicationEvent extends ApplicationEvent {
        private String demo ;
        public DemoApplicationEvent(String demo, EventDto eventDto) {
            super(eventDto);
            this.demo = demo ;
        }
    }

     事件监听者

    @Component
    public class DemoApplicationListener implements ApplicationListener<DemoApplicationEvent> {
        /**
         * Handle an application event.
         *
         * @param event the event to respond to
         */
        @Override
        public void onApplicationEvent(DemoApplicationEvent event) {
            System.out.println(event.getDemo() + " -- " + event.getSource());
        }
    }

     启动springboot:

    @SpringBootApplication
    public class MqStarterApplication {
        public static void main(String[] args) {
            ConfigurableApplicationContext ctx = SpringApplication.run(MqStarterApplication.class, args);
            ctx.publishEvent(new DemoApplicationEvent("hello", new EventDto("pig")));
        }
    }

     运行结果:

    hello -- EventDto(name=pig)

  • 相关阅读:
    Pytorch-情感分类实战(基于LSTM,调用torchtext)
    Pytorch-LSTM
    Pytorch-时间序列预测
    Pytorch-RNN
    SQLServer -------- 包含(charindex)
    .NET ------ 树形菜单,点击单选按钮触发相应事件
    电子秤Xk3190-A12+E 称重方式的设置方法
    串口调试工具与com口编程
    .NET ------ Repeater 遍历数据显示在页面上
    .NET ------ 将弹窗内增加选项卡
  • 原文地址:https://www.cnblogs.com/xiaoxing/p/11397294.html
Copyright © 2020-2023  润新知