• Spring事件


    Spring事件体系包括三个组件:事件,事件监听器,事件广播器

    事件:ApplicationEvent
    事件监听器:ApplicationListener,对监听到的事件进行处理。
    事件广播器:ApplicationEventMulticaster,将Springpublish的事件广播给所有的监听器。
    Spring在ApplicationContext接口的抽象实现类AbstractApplicationContext中完成了事件体系的搭建。
    AbstractApplicationContext拥有一个applicationEventMulticaster成员变 量,applicationEventMulticaster提供了容器监听器的注册表。
    AbstractApplicationContext在refresh()这个容器启动方法中搭建了事件的基础设施。
    refresh
     1     public void refresh() throws BeansException, IllegalStateException {
     2         synchronized (this.startupShutdownMonitor) {
     3             // Prepare this context for refreshing.
     4             prepareRefresh();
     5 
     6             // Tell the subclass to refresh the internal bean factory.
     7             ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
     8 
     9             // Prepare the bean factory for use in this context.
    10             prepareBeanFactory(beanFactory);
    11 
    12             try {
    13                 // Allows post-processing of the bean factory in context subclasses.
    14                 postProcessBeanFactory(beanFactory);
    15 
    16                 // Invoke factory processors registered as beans in the context.
    17                 invokeBeanFactoryPostProcessors(beanFactory);
    18 
    19                 // Register bean processors that intercept bean creation.
    20                 registerBeanPostProcessors(beanFactory);
    21 
    22                 // Initialize message source for this context.
    23                 initMessageSource();
    24 
    25                 // Initialize event multicaster for this context.
    26                 initApplicationEventMulticaster();
    27 
    28                 // Initialize other special beans in specific context subclasses.
    29                 onRefresh();
    30 
    31                 // Check for listener beans and register them.
    32                 registerListeners();
    33 
    34                 // Instantiate all remaining (non-lazy-init) singletons.
    35                 finishBeanFactoryInitialization(beanFactory);
    36 
    37                 // Last step: publish corresponding event.
    38                 finishRefresh();
    39             }
    40 
    41             catch (BeansException ex) {
    42                 // Destroy already created singletons to avoid dangling resources.
    43                 destroyBeans();
    44 
    45                 // Reset 'active' flag.
    46                 cancelRefresh(ex);
    47 
    48                 // Propagate exception to caller.
    49                 throw ex;
    50             }
    51         }
    52     }
    1、事件广播器的初始化:
    View Code
    /**
         * 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.isDebugEnabled()) {
                    logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
                }
            }
            else {
                this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
                beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
                if (logger.isDebugEnabled()) {
                    logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                            APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                            "': using default [" + this.applicationEventMulticaster + "]");
                }
            }
        }

    用户可以在配置文件中为容器定义一个自定义的事件广播器,只要实现ApplicationEventMulticaster就可以了,Spring会通过 反射的机制将其注册成容器的事件广播器,如果没有找到配置的外部事件广播器,Spring自动使用 SimpleApplicationEventMulticaster作为事件广播器。

    2、注册事件监听器

    View Code
    /**
         * 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 lisName : listenerBeanNames) {
                getApplicationEventMulticaster().addApplicationListenerBean(lisName);
            }
        }

     Spring根据反射机制,使用ListableBeanFactory的getBeansOfType方法,从BeanDefinitionRegistry中找出所有实现 org.springframework.context.ApplicationListener的Bean,将它们注册为容器的事件监听器,实际的操作就是将其添加到事件广播器所提供的监听器注册表中。

    3、发布事件

    View Code
        /**
         * Publish the given event to all listeners.
         * <p>Note: Listeners get initialized after the MessageSource, to be able
         * to access it within listener implementations. Thus, MessageSource
         * implementations cannot publish events.
         * @param event the event to publish (may be application-specific or a
         * standard framework event)
         */
        public void publishEvent(ApplicationEvent event) {
            Assert.notNull(event, "Event must not be null");
            if (logger.isTraceEnabled()) {
                logger.trace("Publishing event in " + getDisplayName() + ": " + event);
            }
            getApplicationEventMulticaster().multicastEvent(event);
            if (this.parent != null) {
                this.parent.publishEvent(event);
            }
        }

    AbstractApplicationContext的publishEvent方法中, Spring委托ApplicationEventMulticaster将事件通知给所有的事件监听器

    4、Spring默认的事件广播器SimpleApplicationEventMulticaster

    View Code
    @SuppressWarnings("unchecked")
        public void multicastEvent(final ApplicationEvent event) {
            for (final ApplicationListener listener : getApplicationListeners(event)) {
                Executor executor = getTaskExecutor();
                if (executor != null) {
                    executor.execute(new Runnable() {
                        @SuppressWarnings("unchecked")
                        public void run() {
                            listener.onApplicationEvent(event);
                        }
                    });
                }
                else {
                    listener.onApplicationEvent(event);
                }
            }
        }
    遍历注册的每个监听器,并启动来调用每个监听器的onApplicationEvent方法。
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    不足百行代码 实体数组转DataTable通用类
    【翻译】WEB安全设计规范(4.1)
    也为读者说几句(兼为什么要骂烂书译者)
    重用之前应仔细分析问题用错轮子有感
    最长代码有多长:不符[单一职责原则(SRP)]的常见设计
    "千里之堤毁于蚁穴"重点项目不能交付之谜(一)泥淖中的验收测试
    企业快速开发框架基于配置文件
    从面试题看高级软件工程师需要哪些技艺
    面试英语【转】
    测试
  • 原文地址:https://www.cnblogs.com/atyou/p/2850106.html
Copyright © 2020-2023  润新知