spring中的ApplicationListener

spring中的ApplicationListener是一个监听器,用来监听容器中发布的事件

监听器也是一种观察者设计模式,该接口有一个onApplicationEvent()方法,

在事件发布时,此方法将会调用,实现监听的功能。

/**
 * 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);

}

自定义一个实现了ApplicationListener接口的实现类MyEventListener:

@Component
public class MyEventListener implements ApplicationListener<ApplicationEvent>{

        @Override
        public void onApplicationEvent(ApplicationEvent event) {
            System.out.println("监听到的事件发布。。。。。。。。。。"+event);
        }

}

配置类:

@Configuration
@Import({MyEventListener.class})
public class ExtConfig {
}

测试类:

public class ExtTest {

    @Test
    public void  test(){
        AnnotationConfigApplicationContext  applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
        applicationContext.publishEvent(new ApplicationEvent(new String("我发布的事件")) {});
        applicationContext.close();
    }
}

打印结果:可以看到监听到了容器中三个事件的发布

监听到的事件发布。。。。。。。。。。org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@3339ad8e: 
org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
监听到的事件发布。。。。。。。。。。ExtTest$1[source=我发布的事件]
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@3339ad8e:
监听到的事件发布。。。。。。。。。。org.springframework.context.event.ContextClosedE

发布流程:

refresh()--》finishRefresh()--》publishEvent(new ContextRefreshedEvent(this));
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 = ((PayloadApplicationEvent)applicationEvent).getResolvableType();
            }
        }

        // 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);
            }
        }
    }
执行getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);获取多波器(派发器)
multicastEvent(applicationEvent, eventType):
@Override
    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); } } }

执行:doInvokeListener(listener, event)--》listener.onApplicationEvent(event);

    @SuppressWarnings({"unchecked", "rawtypes"})
    private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
        try {
            listener.onApplicationEvent(event);
        }
        catch (ClassCastException ex) {
            String msg = ex.getMessage();
            if (msg == null || msg.startsWith(event.getClass().getName())) {
                // Possibly a lambda-defined listener which we could not resolve the generic event type for
                Log logger = LogFactory.getLog(getClass());
                if (logger.isDebugEnabled()) {
                    logger.debug("Non-matching event type for listener: " + listener, ex);
                }
            }
            else {
                throw ex;
            }
        }
    }

 最终会去调用具体的onApplicationEvent()方法;

 

猜你喜欢

转载自www.cnblogs.com/tdyang/p/12093449.html