一、ApplicationListener:监听容器中发布的事件。事件驱动模型开发;
public interface ApplicationListener<E extends ApplicationEvent>监听 ApplicationEvent 及其下面的子事件;
1、监听器 MyApplicationListener 实现了 ApplicationListener 类,用来监听 ApplicationEvent及其子类下的某个事件。

@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {

	//当容器中发布此事件以后,方法触发
	@Override
	public void onApplicationEvent(ApplicationEvent event) {

		System.out.println("收到事件:"+event);
	}

}

2、只要容器中有相应事件的发布,我们就能监听到这个事件;
 ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件;
 ContextClosedEvent:关闭容器会发布这个事件;
3、发布一个事件:applicationContext.publishEvent();

@Test
public void test01(){
	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@59906517: startup date [Sun Jun 16 11:36:56 CST 2019]; root of context hierarchy]

二、ApplicationListener 源码解析
ContextRefreshedEvent、IOCTest_Ext$1[source=我发布的时间]、ContextClosedEvent;
1、ContextRefreshedEvent事件:
 (1)、容器创建对象:refresh();

public AnnotationConfigApplicationContext(Class... annotatedClasses) {
    this();
    this.register(annotatedClasses);
    this.refresh();
}
public void refresh() throws BeansException, IllegalStateException {
    Object var1 = this.startupShutdownMonitor;
    synchronized(this.startupShutdownMonitor) {
        this.prepareRefresh();
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
        this.prepareBeanFactory(beanFactory);

        try {
            this.postProcessBeanFactory(beanFactory);
            this.invokeBeanFactoryPostProcessors(beanFactory);
            this.registerBeanPostProcessors(beanFactory);
            this.initMessageSource();
            this.initApplicationEventMulticaster();
            this.onRefresh();
            this.registerListeners();
            this.finishBeanFactoryInitialization(beanFactory);
            this.finishRefresh();
        } catch (BeansException var9) {
            if (this.logger.isWarnEnabled()) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
            }

            this.destroyBeans();
            this.cancelRefresh(var9);
            throw var9;
        } finally {
            this.resetCommonCaches();
        }

    }
}

  initApplicationEventMulticaster();初始化ApplicationEventMulticaster;
    1)、先去容器中找有没有id=“applicationEventMulticaster”的组件;
    2)、如果没有this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);并且加入到容器中,我们就可以在其他组件要派发事件,自动注入这个applicationEventMulticaster。
  registerListeners();从容器中拿到所有的监听器,把他们注册到applicationEventMulticaster中;

String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
//将listener注册到ApplicationEventMulticaster中
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);

 (2)、finishRefresh():容器刷新完成会发布ContextRefreshedEvent事件;

protected void finishRefresh() {
    this.initLifecycleProcessor();
    this.getLifecycleProcessor().onRefresh();
    this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
    LiveBeansView.registerApplicationContext(this);
}

 (3)、publishEvent(new ContextRefreshedEvent(this));
   1)、获取事件的多播器(派发器):getApplicationEventMulticaster()
   2)、multicastEvent派发事件;
   3)、获取到所有的ApplicationListener;
     for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {}
     如果有Executor,可以支持使用Executor进行异步派发;Executor executor = getTaskExecutor()
     否则,同步的方式直接执行listener方法;invokeListener(listener, event); 拿到listener回调onApplicationEvent方法;

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

    Object applicationEvent;
    if (event instanceof ApplicationEvent) {
        applicationEvent = (ApplicationEvent)event;
    } else {
        applicationEvent = new PayloadApplicationEvent(this, event);
        if (eventType == null) {
            eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType();
        }
    }

    if (this.earlyApplicationEvents != null) {
        this.earlyApplicationEvents.add(applicationEvent);
    } else {
        this.getApplicationEventMulticaster().multicastEvent((ApplicationEvent)applicationEvent, eventType);
    }

    if (this.parent != null) {
        if (this.parent instanceof AbstractApplicationContext) {
            ((AbstractApplicationContext)this.parent).publishEvent(event, eventType);
        } else {
            this.parent.publishEvent(event);
        }
    }

}
public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
    ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);
    Iterator var4 = this.getApplicationListeners(event, type).iterator();

    while(var4.hasNext()) {
        final ApplicationListener<?> listener = (ApplicationListener)var4.next();
        Executor executor = this.getTaskExecutor();
        if (executor != null) {
            executor.execute(new Runnable() {
                public void run() {
                    SimpleApplicationEventMulticaster.this.invokeListener(listener, event);
                }
            });
        } else {
            this.invokeListener(listener, event);
        }
    }

}
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
    ErrorHandler errorHandler = this.getErrorHandler();
    if (errorHandler != null) {
        try {
            this.doInvokeListener(listener, event);
        } catch (Throwable var5) {
            errorHandler.handleError(var5);
        }
    } else {
        this.doInvokeListener(listener, event);
    }

}
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
    try {
        listener.onApplicationEvent(event);
    } catch (ClassCastException var6) {
        String msg = var6.getMessage();
        if (msg != null && !msg.startsWith(event.getClass().getName())) {
            throw var6;
        }

        Log logger = LogFactory.getLog(this.getClass());
        if (logger.isDebugEnabled()) {
            logger.debug("Non-matching event type for listener: " + listener, var6);
        }
    }

}

2、自己发布事件;applicationContext.publishEvent();
3、容器关闭会发布ContextClosedEvent;applicationContext.close();

public void close() {
    Object var1 = this.startupShutdownMonitor;
    synchronized(this.startupShutdownMonitor) {
        this.doClose();
        if (this.shutdownHook != null) {
            try {
                Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
            } catch (IllegalStateException var4) {
                ;
            }
        }

    }
}
protected void doClose() {
    if (this.active.get() && this.closed.compareAndSet(false, true)) {
        if (this.logger.isInfoEnabled()) {
            this.logger.info("Closing " + this);
        }

        LiveBeansView.unregisterApplicationContext(this);

        try {
            this.publishEvent((ApplicationEvent)(new ContextClosedEvent(this)));
        } catch (Throwable var3) {
            this.logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", var3);
        }

        try {
            this.getLifecycleProcessor().onClose();
        } catch (Throwable var2) {
            this.logger.warn("Exception thrown from LifecycleProcessor on context close", var2);
        }

        this.destroyBeans();
        this.closeBeanFactory();
        this.onClose();
        this.active.set(false);
    }

}
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐