一、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);
}
}