Springboot內建ApplicationListener--DelegatingApplicationListener
阿新 • • 發佈:2018-11-19
原始碼分析
本文原始碼基於 Springboot 2.1.0
package org.springframework.boot.context.config;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.core.Ordered;
import org. springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* ApplicationListener that delegates to other listeners that are specified under
* a context.listener.classes environment property.
*
* 監聽應用事件,並將這些應用事件廣播給環境屬性context.listener.classes指定的那些監聽器。
*
* @author Dave Syer
* @author Phillip Webb
*/
public class DelegatingApplicationListener
implements ApplicationListener<ApplicationEvent>, Ordered {
// NOTE: Similar to org.springframework.web.context.ContextLoader
private static final String PROPERTY_NAME = "context.listener.classes";
private int order = 0;
private SimpleApplicationEventMulticaster multicaster;
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationEnvironmentPreparedEvent) {
// 聽到ApplicationEnvironmentPreparedEvent事件時,嘗試根據環境屬性
// context.listener.classes構造相應的事件監聽器
List<ApplicationListener<ApplicationEvent>> delegates = getListeners(
((ApplicationEnvironmentPreparedEvent) event).getEnvironment());
if (delegates.isEmpty()) {
return;
}
// 如果環境屬性context.listener.classes指定了有效的事件監聽器,構造一個
// 事件多播器,將所有這些事件監聽器登記到該多播器上。
this.multicaster = new SimpleApplicationEventMulticaster();
for (ApplicationListener<ApplicationEvent> listener : delegates) {
this.multicaster.addApplicationListener(listener);
}
}
// 如果是ApplicationEnvironmentPreparedEvent之外的其他應用事件,將該事件
// 直接通過事件多播器廣播到環境屬性context.listener.classes指定的那些事件監聽器上。
if (this.multicaster != null) {
this.multicaster.multicastEvent(event);
}
}
@SuppressWarnings("unchecked")
private List<ApplicationListener<ApplicationEvent>> getListeners(
ConfigurableEnvironment environment) {
if (environment == null) {
return Collections.emptyList();
}
// 獲取環境屬性context.listener.classes指定的事件監聽器的類名稱,0個或者多個,使用逗號分隔
String classNames = environment.getProperty(PROPERTY_NAME);
List<ApplicationListener<ApplicationEvent>> listeners = new ArrayList<>();
if (StringUtils.hasLength(classNames)) {
for (String className : StringUtils.commaDelimitedListToSet(classNames)) {
// 建立每個事件監聽器的一個例項
try {
Class<?> clazz = ClassUtils.forName(className,
ClassUtils.getDefaultClassLoader());
Assert.isAssignable(ApplicationListener.class, clazz, "class ["
+ className + "] must implement ApplicationListener");
listeners.add((ApplicationListener<ApplicationEvent>) BeanUtils
.instantiateClass(clazz));
}
catch (Exception ex) {
throw new ApplicationContextException(
"Failed to load context listener class [" + className + "]",
ex);
}
}
}
// 根據事件多播器上的排序註解屬性對它們進行排序
AnnotationAwareOrderComparator.sort(listeners);
return listeners;
}
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return this.order;
}
}