spring中ApplicationListener源码分析

最近做一个功能,需要在整个服务器容器加载完成就触发执行,这个时候我只需要实现ApplicationListener即可。spring的这个接口就是给一个观察的入口,可以在各个阶段去触发相应的操作。不难看出这就是典型的设计模式之观察者模式。这次我们以观察者的观点去分析一下ApplicationListener。

/** * Interface to be implemented by application event listeners. * Based on the standard {@code java.util.EventListener} interface * for the Observer design pattern. * * <p>As of Spring 3.0, an ApplicationListener can generically declare the event type * that it is interested in. When registered with a Spring ApplicationContext, events * will be filtered accordingly, with the listener getting invoked for matching event * objects only. * * @author Rod Johnson * @author Juergen Hoeller * @param <E> the specific ApplicationEvent subclass to listen to * @see org.springframework.context.event.ApplicationEventMulticaster */
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

    /** * Handle an application event. * @param event the event to respond to */
    void onApplicationEvent(E event);

}

Rod Johnson大神也在注释里写清楚了这个功能就是基于观察者模式,并且用户可以在实现类中指定自己感兴趣的事件观察。这个就是所有观察者的抽象接口,这个接口是给客户端使用的,客户端只是对接口透明,对具体的需要通知的对象是动态注入的。一旦观察者感兴趣的事件发生,客户端就会调用接口的方法通知。
这个通知方法,就是在:org.springframework.context.event.SimpleApplicationEventMulticaster中的:

protected void invokeListener(ApplicationListener listener, ApplicationEvent event) {
        ErrorHandler errorHandler = getErrorHandler();
        if (errorHandler != null) {
            try {
                listener.onApplicationEvent(event);
            }
            catch (Throwable err) {
                errorHandler.handleError(err);
            }
        }
        else {
            listener.onApplicationEvent(event);
        }
    }

这里只是通知一个观察者,具体要通知哪些观察者在该类的父类org.springframework.context.event.SimpleApplicationEventMulticaster定义一种事件类型的观察者有哪些(ApplicationListener):

public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
        ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
        for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
            Executor executor = getTaskExecutor();
            if (executor != null) {
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        invokeListener(listener, event);
                    }
                });
            }
            else {
                invokeListener(listener, event);
            }
        }
    }

所有的监听器的注册在org.springframework.context.support.AbstractApplicationContext的refresh()方法当中的registerListener()方法,该方法基本完成了容器的初始化:

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 listenerBeanName : listenerBeanNames) {
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        // Publish early application events now that we finally have a multicaster...
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }

当容器初始化结束后就会调用finishRefresh(),该事件会触发一系列操作,其中就包括通知观察者,即监听器:

protected void publishEvent(Object event, ResolvableType eventType) {
        Assert.notNull(event, "Event must not be null");
        if (logger.isTraceEnabled()) {
            logger.trace("Publishing event in " + getDisplayName() + ": " + event);
        }

        // Decorate event as an ApplicationEvent if necessary
        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());
            }
        }

        // Multicast right now if possible - or lazily once the multicaster is initialized
        if (this.earlyApplicationEvents != null) {
            this.earlyApplicationEvents.add(applicationEvent);
        }
        else {
            getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
        }

        // Publish event via parent context as well...
        if (this.parent != null) {
            if (this.parent instanceof AbstractApplicationContext) {
                ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
            }
            else {
                this.parent.publishEvent(event);
            }
        }
    }

以上代码是根据事件去通知对应的监听器。这里的具体情况是在finishRefresh()传入了容器加载完成事件:
这样就去调用对这个事件感兴趣的监听器。

        // Publish the final event.
        publishEvent(new ContextRefreshedEvent(this));

这里完成接口调用通知。

public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
        ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
        for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
            Executor executor = getTaskExecutor();
            if (executor != null) {
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        invokeListener(listener, event);
                    }
                });
            }
            else {
                invokeListener(listener, event);
            }
        }
    }

这样就用观察者模式实现了spring的整个事件监听功能。

    原文作者:Spring Boot
    原文地址: https://blog.csdn.net/micro_hz/article/details/71303557
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞