ApplicationContext系列七初始化ApplicationEventMulticaster

在说清楚spring的事件传播器之前,先回顾下spring的事件监听机制

一、事件监听

public class TestEvent extends ApplicationEvent {
    private String message;
    public TestEvent(Object source) {
        super(source);
    }
    public TestEvent(Object source,String message) {
        super(source);
        this.message=message;
    }
    public void print(){
        System.out.println(message);
    }
}
public class TestListener implements ApplicationListener {
    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        if(applicationEvent instanceof TestEvent){
            TestEvent testEvent=(TestEvent)applicationEvent;
            testEvent.print();
        }
    }
}
<bean id="testListener" class="com.springboot2.test.TestListener"></bean>
ApplicationContext sc=new ClassPathXmlApplicationContext("beans.xml");
TestEvent testEvent = new TestEvent("hello", "spring");
sc.publishEvent(testEvent);

二、源码分析

1、事件广播

protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
    if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
        this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    } else {
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("No 'applicationEventMulticaster' bean, using [" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
        }
    }

}

按照之前介绍的顺序和逻辑,作为广播器,一定是用于存放监听器并在合适的时候调用监听器。

SimpleApplicationEventMulticaster是默认的广播实现,查看该默认的广播器中multicastEvent方法

public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {
    ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);
    Executor executor = this.getTaskExecutor();
    Iterator var5 = this.getApplicationListeners(event, type).iterator();

    while(var5.hasNext()) {
        ApplicationListener<?> listener = (ApplicationListener)var5.next();
        if (executor != null) {
            executor.execute(() -> {
                this.invokeListener(listener, event);
            });
        } else {
            this.invokeListener(listener, event);
        }
    }

}

当spring产生事件时候会默认使用SimpleApplicationEventMulticastermulticastEvent方法来广播事件,遍历所有监听器,并使用监听器中的onApplicationEvent进行监听器的处理。对于每一个监听器而言,其实都可以获取到spring的事件,但是是否需要处理,是由具体的监听器来决定。

2、注册监听器

protected void registerListeners() {
        Iterator var1 = this.getApplicationListeners().iterator();
        //硬编码方式注册监听器
        while(var1.hasNext()) {
            ApplicationListener<?> listener = (ApplicationListener)var1.next();
            this.getApplicationEventMulticaster().addApplicationListener(listener);
        }

        //配置文件注册监听器
        String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false);
        String[] var7 = listenerBeanNames;
        int var3 = listenerBeanNames.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            String listenerBeanName = var7[var4];
            this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
            Iterator var9 = earlyEventsToProcess.iterator();

            while(var9.hasNext()) {
                ApplicationEvent earlyEvent = (ApplicationEvent)var9.next();
                this.getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }

    }

注册监听器有两个途径:编码注册,配置文件注册

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值