3. Spring是如何发布事件的? ApplicationListener

1.1)自己写一个TulingApplicationListener 实现ApplicationListener 接口,并且把该组件加入到容器中.

@Component 
public class TulingApplicationListener implements ApplicationListener {     
    //接受到消息,回调该方法     
    @Override     
    public void onApplicationEvent(ApplicationEvent event) {         System.out.println("TulingApplicationListener 接受到了一个事件"+event);     
    } 
 } 
    
 public static void main(String[] args) {         AnnotationConfigApplicationContext ctx = 
            new AnnotationConfigApplicationContext(MainConfig.class);
             //手动发布一个事件         
            ctx.publishEvent(new ApplicationEvent("我手动发布了一个事件") {
                @Override             
                public Object getSource() {
                         return super.getSource(); 
                }        
            });                  
    //容器关闭也发布事件        
 ctx.close();     
} 
 

测试结果: TulingApplicationListener 接受到了一个事件org.springframework.context.event.ContextRefreshedEvent[source=org.springframewo TulingApplicationListener 接受到了一个事件com.tuling.testapplicationlistener.MainClass$1[source=我手动发布了一个事件] TulingApplicationListener 接受到了一个事件org.springframework.context.event.ContextClosedEvent[source=org.springframework

 

源码解析:
i1>org.springframework.context.support.AbstractApplicationContext#refresh
   i2>org.springframework.context.support.AbstractApplicationContext#initApplicationEventMulticaster(初 始化事件多播器)
       i3>org.springframework.context.support.AbstractApplicationContext#registerListeners(把事件监听 器注册到多播器上去)
i2(初始化事件多播器源码解析)
 

protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
/判断IOC容器中包含applicationEventMulticaster 事件多播器的Bean的name
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
/创建一个applicationEventMulticaster的bean放在IOC 容器中,bean的name 为applicationEventMulticaster
this.applicationEventMulticaster =beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
/容器中不包含一个beanName 为applicationEventMulticaster的多播器组件
else {
//创建一个SimpleApplicationEventMulticaster 多播器
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 + "]");
}
}
}
i3:把容器中的监听器注册到多播器上去 源码解析
protected void registerListeners() {
    //去容器中把applicationListener 捞取出来注册到多播器上去(系统的)
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }
    //我们自己实现了ApplicationListener 的组件
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }
    //在这里之前,我们早期想发布的事件 由于没有多播器没有发布,在这里我们总算有了自己的多播器,可以在这里发布早期堆积的事件
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}
--------------------------------------------------------------------如何发布事件------------------------------------------------------
public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
      ResolvableType type = (eventType != null ? eventType :        
    resolveDefaultEventType(event));
    //获取到所有的监听器
      for (final ApplicationListener<?> listener : getApplicationListeners(event, type))                 {
    //看spring 容器中是否支持线程池 异步发送事件
    Executor executor = getTaskExecutor();
    if (executor != null) {
        executor.execute(new Runnable() {
        @Override
        public void run() {
            invokeListener(listener, event);
        }
        });
    }
    else { //同步发送事件
        invokeListener(listener, event);
    }
    }
}
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
    try {
        //调用对于listener的onApplicationEvent事件
        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;
        }
    }
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JackXiang2019

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值