zoukankan      html  css  js  c++  java
  • Spring ApplicationContext(八)事件监听机制

    Spring ApplicationContext(八)事件监听机制

    本节则重点关注的是 Spring 的事件监听机制,主要是第 8 步:多播器注册;第 10 步:事件注册。

    public void refresh() throws BeansException, IllegalStateException {
        // 8. 注册多播器,事件监听器的管理者
        initApplicationEventMulticaster();
        // 9. 专门留给子类初始化其它 bean 用,这是一个空的方法
        onRefresh();
        // 10. 注册监听器
        registerListeners();
    }
    

    事件定义如下,实现了 JDK 的规范 EventListener

    public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
        // 监听 event 事件
        void onApplicationEvent(E event);
    }
    

    一、ApplicationListener 实战

    import org.springframework.context.ApplicationEvent;
    import org.springframework.context.ApplicationListener;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
    
        @Override
        public void onApplicationEvent(ApplicationEvent event) {
            System.out.println("接收的事件:" + event);
        }
    }
    

    运行后结果如下:

    接收的事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.support.ClassPathXmlApplicationContext@16eabae: startup date [Sun Jul 29 12:41:42 CST 2018]; root of context hierarchy]
    

    二、ApplicationEventMulticaster 多播器的初始化

    ApplicationContext 中 refresh() 第 8 步 initApplicationEventMulticaster() 进行多播器的初始化工作

    源代码【AbstractApplicationContext】

    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);
        }
        else {
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
        }
    }
    

    三、ApplicationListener 注册

    ApplicationContext 中 refresh() 第 10 步 registerListeners() 进行事件监听者的注册工作。

    源代码【AbstractApplicationContext】

    protected void registerListeners() {
        // 1. 注册静态指定的侦听器
        for (ApplicationListener<?> listener : getApplicationListeners()) {
            getApplicationEventMulticaster().addApplicationListener(listener);
        }
    
        // 2. 注册 ApplicationListener
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }
    
        // 3. Publish early application events
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }
    

    四、ApplicationEvent 事件发布

    源代码【AbstractApplicationContext】

    public void publishEvent(ApplicationEvent event) {
        publishEvent(event, null);
    }
    
    public void publishEvent(Object event) {
        publishEvent(event, null);
    }
    
    protected void publishEvent(Object event, ResolvableType eventType) {
        Assert.notNull(event, "Event must not be null");
       
        // 1. 如果 event 不是 ApplicationEvent,则需要进行封装成 PayloadApplicationEvent
        ApplicationEvent applicationEvent;
        if (event instanceof ApplicationEvent) {
            applicationEvent = (ApplicationEvent) event;
        }
        else {
            applicationEvent = new PayloadApplicationEvent<Object>(this, event);
            if (eventType == null) {
                eventType = ResolvableType.forClassWithGenerics(PayloadApplicationEvent.class, event.getClass());
            }
        }
    
        // 2. 发布事件 event,如果多播器懒加载,还没有初始化则将该事件先放到 earlyApplicationEvents 容器中
        //    等待多播器创建好了再发布事件 ???
        if (this.earlyApplicationEvents != null) {
            this.earlyApplicationEvents.add(applicationEvent);
        }
        else {
            getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
        }
    
        // 3. 父容器中也需要发布该事件 event
        if (this.parent != null) {
            if (this.parent instanceof AbstractApplicationContext) {
                ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
            }
            else {
                this.parent.publishEvent(event);
            }
        }
    }
    

    每天用心记录一点点。内容也许不重要,但习惯很重要!

  • 相关阅读:
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    微信小程序TodoList
    C语言88案例-找出数列中的最大值和最小值
    C语言88案例-使用指针的指针输出字符串
  • 原文地址:https://www.cnblogs.com/binarylei/p/10423695.html
Copyright © 2011-2022 走看看