前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring事件监听机制

Spring事件监听机制

作者头像
Java学习录
发布2019-09-19 11:12:33
1.4K0
发布2019-09-19 11:12:33
举报
文章被收录于专栏:Java学习录Java学习录
前言

Spring中的事件机制其实就是设计模式中的观察者模式,主要由以下角色构成:

  1. 事件
  2. 事件监听器(监听并处理事件)
  3. 事件发布者(发布事件)

首先看一下监听器和发布者的接口定义

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
      void onApplicationEvent(E event);
  }
  
  public interface ApplicationEventPublisher {
	default void publishEvent(ApplicationEvent event) {
		publishEvent((Object) event);
	}
	void publishEvent(Object event);

}
事件流转流程
初始化事件广播器

看一下这个方法AbstractApplicationContext.refresh,在IOC源码解析那篇文章已经把这个方法分析完了,所以直接关注事件广播器和事件发布相关的逻辑即可


 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();
 
                // 初始化事件广播器
                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);
 
                // 发布事件
                finishRefresh();
            }
 
            catch (BeansException ex) {
                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;
            }
        }
}

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 + "]");
            }
        }
    }

可以看到如果没有自定义的事件广播器,默认是使用SimpleApplicationEventMulticaster

发布事件

发布事件是在bean的初始化之后的


    protected void finishRefresh() {
        // Initialize lifecycle processor for this context.
        initLifecycleProcessor();
 
        // Propagate refresh to lifecycle processor first.
        getLifecycleProcessor().onRefresh();
 
        // 发布事件
        publishEvent(new ContextRefreshedEvent(this));
 
        // Participate in LiveBeansView MBean, if active.
        LiveBeansView.registerApplicationContext(this);
    }


public void publishEvent(ApplicationEvent event) {
        Assert.notNull(event, "Event must not be null");
        if (logger.isTraceEnabled()) {
            logger.trace("Publishing event in " + getDisplayName() + ": " + event);
        }
        //1. 获取到事件广播器,发布事件
        getApplicationEventMulticaster().multicastEvent(event);
        //2. 如果存在父容器,父容器也将发布事件
        if (this.parent != null) {
            this.parent.publishEvent(event);
        }
    }

具体的发布逻辑在multicastEvent方法中


public void multicastEvent(final ApplicationEvent event) {
        //遍历执行listener,getApplicationListeners调用AbstractApplicationEventMulticaster父类方法
        for (final ApplicationListener listener : getApplicationListeners(event)) {
            Executor executor = getTaskExecutor();
            if (executor != null) {
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        listener.onApplicationEvent(event);
                    }
                });
            }
            else {
                listener.onApplicationEvent(event);
            }
        }
    }

可以看到也没啥特殊的,无非就是起个线程池去调用这些监听器的方法

而监听器的处理就看各个监听器的具体实现了

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java学习录 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 事件流转流程
    • 初始化事件广播器
      • 发布事件
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档