接着上章所讲的EventPublishingRunListener的构造方法:
SimpleApplicationEventMulticaster是ApplicationEventMulticaster接口的简单实现。它将所有事件多播到所有注册的监听器,让监听器忽略他们不感兴趣的事件。监听器通常会对传入的事件对象执行相应的instanceof检查。默认情况下,所有监听器监听器都在调用线程中调用,这会增加恶意监听器阻塞整个应用程序的危险性。所以最好指定一个替代任务执行器,让监听器在不同的线程中执行,例如从线程池中执行。
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
@Nullable
private Executor taskExecutor;
@Nullable
private ErrorHandler errorHandler;
@Nullable
private volatile Log lazyLogger;
/**
* 创建一个新的 SimpleApplicationEventMulticaster。
*/
public SimpleApplicationEventMulticaster() {
}
/**
* 为给定的 BeanFactory 创建一个新的 SimpleApplicationEventMulticaster。
*/
public SimpleApplicationEventMulticaster(BeanFactory beanFactory) {
setBeanFactory(beanFactory);
}
/**
* 设置一个自定义执行器(通常是org.springframework.core.task.TaskExecutor )来调用每个监听器。
* 默认相当于org.springframework.core.task.SyncTaskExecutor ,在调用线程中同步执行所有监听器。
* 考虑在此处指定一个异步任务执行器,以在所有监听器都已执行之前不阻塞调用者。但是,请注意,异步执行不会参与调用者的线程上下文(类加载器、事务关联),除非 TaskExecutor 明确支持这一点。
*/
public void setTaskExecutor(@Nullable Executor taskExecutor) {
this.taskExecutor = taskExecutor;
}
/**
* 返回此多播器的当前任务执行器。
*/
@Nullable
protected Executor getTaskExecutor() {
return this.taskExecutor;
}
/**
* 设置ErrorHandler以在侦听器抛出异常时调用。默认值为无,侦听器异常会停止当前多播并传播到当前事件的发布者。
* 如果指定了任务执行器,则每个单独的侦听器异常都会传播到执行器,但不一定会停止其他侦听器的执行。
* 考虑设置一个捕获和记录异常的ErrorHandler实现(例如org.springframework.scheduling.support.TaskUtils.LOG_AND_SUPPRESS_ERROR_HANDLER )或一个在传播异常的同时记录异常的实现(例如org.springframework.scheduling.support.TaskUtils.LOG_AND_PROPAGATE_ERROR_HANDLER )。
*/
public void setErrorHandler(@Nullable ErrorHandler errorHandler) {
this.errorHandler = errorHandler;
}
/**
* 返回此多播器的当前错误处理程序。
*/
@Nullable
protected ErrorHandler getErrorHandler() {
return this.errorHandler;
}
@Override
public void multicastEvent(ApplicationEvent event) {
multicastEvent(event, resolveDefaultEventType(event));
}
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
private ResolvableType resolveDefaultEventType(ApplicationEvent event) {
return ResolvableType.forInstance(event);
}
/**
* 使用给定事件调用给定监听器。
*/
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
doInvokeListener(listener, event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
doInvokeListener(listener, event);
}
}
@SuppressWarnings({"rawtypes", "unchecked"})
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass()) ||
(event instanceof PayloadApplicationEvent &&
matchesClassCastMessage(msg, ((PayloadApplicationEvent) event).getPayload().getClass()))) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
// -> let's suppress the exception.
Log loggerToUse = this.lazyLogger;
if (loggerToUse == null) {
loggerToUse = LogFactory.getLog(getClass());
this.lazyLogger = loggerToUse;
}
if (loggerToUse.isTraceEnabled()) {
loggerToUse.trace("Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}
private boolean matchesClassCastMessage(String classCastMessage, Class<?> eventClass) {
// On Java 8, the message starts with the class name: "java.lang.String cannot be cast..."
if (classCastMessage.startsWith(eventClass.getName())) {
return true;
}
// On Java 11, the message starts with "class ..." a.k.a. Class.toString()
if (classCastMessage.startsWith(eventClass.toString())) {
return true;
}
// On Java 9, the message used to contain the module name: "java.base/java.lang.String cannot be cast..."
int moduleSeparatorIndex = classCastMessage.indexOf('/');
if (moduleSeparatorIndex != -1 && classCastMessage.startsWith(eventClass.getName(), moduleSeparatorIndex + 1)) {
return true;
}
// Assuming an unrelated class cast failure...
return false;
}
}
遍历到调用此构造函数时SpringApplication的所有监听器,将它们添加到DefaultListenerRetriever类的成员字段applicationListeners中。addApplicationListener是AbstractApplicationEventMulticaster的方法:
public void addApplicationListener(ApplicationListener<?> listener) {
synchronized (this.defaultRetriever) {
// Explicitly remove target for a proxy, if registered already,
// in order to avoid double invocations of the same listener.
Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);
if (singletonTarget instanceof ApplicationListener) {
this.defaultRetriever.applicationListeners.remove(singletonTarget);
}
this.defaultRetriever.applicationListeners.add(listener);
this.retrieverCache.clear();
}
}
private class DefaultListenerRetriever {
public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
public final Set<String> applicationListenerBeans = new LinkedHashSet<>();
public Collection<ApplicationListener<?>> getApplicationListeners() {
List<ApplicationListener<?>> allListeners = new ArrayList<>(
this.applicationListeners.size() + this.applicationListenerBeans.size());
allListeners.addAll(this.applicationListeners);
if (!this.applicationListenerBeans.isEmpty()) {
BeanFactory beanFactory = getBeanFactory();
for (String listenerBeanName : this.applicationListenerBeans) {
try {
ApplicationListener<?> listener =
beanFactory.getBean(listenerBeanName, ApplicationListener.class);
if (!allListeners.contains(listener)) {
allListeners.add(listener);
}
}
catch (NoSuchBeanDefinitionException ex) {
// Singleton listener instance (without backing bean definition) disappeared -
// probably in the middle of the destruction phase
}
}
}
AnnotationAwareOrderComparator.sort(allListeners);
return allListeners;
}
}
版权声明:本文为BlackReimu原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。