ApplicationListener系列文章
入口
AbstractApplicationContext
org.springframework.context.support.AbstractApplicationContext#publishEvent(java.lang.Object)
@Override
public void publishEvent(ApplicationEvent event) {
publishEvent(event, null);
}
/**发送事件*/
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
// Decorate event as an ApplicationEvent if necessary
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
applicationEvent = new PayloadApplicationEvent<>(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);
}
}
}
广播事件
SimpleApplicationEventMulticaster
SimpleApplicationEventMulticaster:简单的事件广播实现,multicastEvent方法。
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
//线程池,setTaskExecutor就可以实现异步处理了!!!
Executor executor = getTaskExecutor();
//根据Event和type,获取对应的Listener,其实主要是Event判断获取,存在多个情景,
//此时就会存在,如果Listner执行监听业务失败,导致其他Listener无法执行
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
//没有设置线程池,忽略。如果用线程池,就没有一个监听执行失败,影响其他监听的场景了
//因为线程池,天生会吃掉异常。
executor.execute(() -> invokeListener(listener, event));
}
else {
//调用Listener
invokeListener(listener, event);
}
}
}
/**实际调用Listener*/
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
ErrorHandler errorHandler = getErrorHandler();
//errorHandler也是没有定义,忽略
if (errorHandler != null) {
try {
doInvokeListener(listener, event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
//实际的执行
doInvokeListener(listener, event);
}
}
/**执行了*/
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
//onApplicationEvent,这就是自定义Listener的实现接口
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
// -> let's suppress the exception and just log a debug message.
Log logger = LogFactory.getLog(getClass());
if (logger.isTraceEnabled()) {
logger.trace("Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}
根据Event获取Listener
AbstractApplicationEventMulticaster
org.springframework.context.event.AbstractApplicationEventMulticaster#getApplicationListeners(org.springframework.context.ApplicationEvent, org.springframework.core.ResolvableType)
/**根据事件,获取对应的监听*/
protected Collection<ApplicationListener<?>> getApplicationListeners(
ApplicationEvent event, ResolvableType eventType) {
Object source = event.getSource();
Class<?> sourceType = (source != null ? source.getClass() : null);
//缓存key,根据ListenerKey的equals方法,可以推测出Listener与Event的映射关系
ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
// Quick check for existing entry on ConcurrentHashMap...
ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
if (retriever != null) {
return retriever.getApplicationListeners();
}
if (this.beanClassLoader == null ||
(ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
// Fully synchronized building and caching of a ListenerRetriever
synchronized (this.retrievalMutex) {
retriever = this.retrieverCache.get(cacheKey);
if (retriever != null) {
return retriever.getApplicationListeners();
}
retriever = new ListenerRetriever(true);
Collection<ApplicationListener<?>> listeners =
retrieveApplicationListeners(eventType, sourceType, retriever);
this.retrieverCache.put(cacheKey, retriever);
return listeners;
}
}
else {
// No ListenerRetriever caching -> no synchronization necessary
return retrieveApplicationListeners(eventType, sourceType, null);
}
}
//获取监听器的核心方法
private Collection<ApplicationListener<?>> retrieveApplicationListeners(
ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable ListenerRetriever retriever) {
List<ApplicationListener<?>> allListeners = new ArrayList<>();
Set<ApplicationListener<?>> listeners;
Set<String> listenerBeans;
synchronized (this.retrievalMutex) {
listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
}
// Add programmatically registered listeners, including ones coming
// from ApplicationListenerDetector (singleton beans and inner beans).
for (ApplicationListener<?> listener : listeners) {
//判断当前当前监听,是否支持该Event和Source
if (supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
retriever.applicationListeners.add(listener);
}
allListeners.add(listener);
}
}
// Add listeners by bean name, potentially overlapping with programmatically
// registered listeners above - but here potentially with additional metadata.
if (!listenerBeans.isEmpty()) {
ConfigurableBeanFactory beanFactory = getBeanFactory();
for (String listenerBeanName : listenerBeans) {
try {
if (supportsEvent(beanFactory, listenerBeanName, eventType)) {
ApplicationListener<?> listener =
beanFactory.getBean(listenerBeanName, ApplicationListener.class);
if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
if (beanFactory.isSingleton(listenerBeanName)) {
retriever.applicationListeners.add(listener);
}
else {
retriever.applicationListenerBeans.add(listenerBeanName);
}
}
allListeners.add(listener);
}
}
else {
// Remove non-matching listeners that originally came from
// ApplicationListenerDetector, possibly ruled out by additional
// BeanDefinition metadata (e.g. factory method generics) above.
Object listener = beanFactory.getSingleton(listenerBeanName);
if (retriever != null) {
retriever.applicationListeners.remove(listener);
}
allListeners.remove(listener);
}
}
catch (NoSuchBeanDefinitionException ex) {
// Singleton listener instance (without backing bean definition) disappeared -
// probably in the middle of the destruction phase
}
}
}
AnnotationAwareOrderComparator.sort(allListeners);
if (retriever != null && retriever.applicationListenerBeans.isEmpty()) {
retriever.applicationListeners.clear();
retriever.applicationListeners.addAll(allListeners);
}
return allListeners;
}
supportsEvent
protected boolean supportsEvent(
ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {
//普通的监听,都是实现ApplicationListener,因此还需要通过适配器转换。
GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
(GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
}
GenericApplicationListenerAdapter
监听器的适配,supportEevent主要通过该方法进行处理。
事件类型是否匹配
public boolean supportsEventType(ResolvableType eventType) {
if (this.delegate instanceof SmartApplicationListener) {
Class<? extends ApplicationEvent> eventClass = (Class<? extends ApplicationEvent>) eventType.resolve();
return (eventClass != null && ((SmartApplicationListener) this.delegate).supportsEventType(eventClass));
}
else {
return (this.declaredEventType == null || this.declaredEventType.isAssignableFrom(eventType));
}
}
事件比较的核心:this.declaredEventType.isAssignableFrom*(eventType)),即:ResolvableType的类型比较*
ResolvableType
public boolean isAssignableFrom(ResolvableType other) {
return isAssignableFrom(other, null);
}
//实际比较
private boolean isAssignableFrom(ResolvableType other, @Nullable Map<Type, Type> matchedBefore) {
Assert.notNull(other, "ResolvableType must not be null");
// If we cannot resolve types, we are not assignable
if (this == NONE || other == NONE) {
return false;
}
// Deal with array by delegating to the component type
if (isArray()) {
return (other.isArray() && getComponentType().isAssignableFrom(other.getComponentType()));
}
if (matchedBefore != null && matchedBefore.get(this.type) == other.type) {
return true;
}
// Deal with wildcard bounds
WildcardBounds ourBounds = WildcardBounds.get(this);
WildcardBounds typeBounds = WildcardBounds.get(other);
// In the form X is assignable to <? extends Number>
if (typeBounds != null) {
return (ourBounds != null && ourBounds.isSameKind(typeBounds) &&
ourBounds.isAssignableFrom(typeBounds.getBounds()));
}
// In the form <? extends Number> is assignable to X...
if (ourBounds != null) {
return ourBounds.isAssignableFrom(other);
}
// Main assignability check about to follow
boolean exactMatch = (matchedBefore != null); // We're checking nested generic variables now...
boolean checkGenerics = true;
Class<?> ourResolved = null;
if (this.type instanceof TypeVariable) {
TypeVariable<?> variable = (TypeVariable<?>) this.type;
// Try default variable resolution
if (this.variableResolver != null) {
ResolvableType resolved = this.variableResolver.resolveVariable(variable);
if (resolved != null) {
ourResolved = resolved.resolve();
}
}
if (ourResolved == null) {
// Try variable resolution against target type
if (other.variableResolver != null) {
ResolvableType resolved = other.variableResolver.resolveVariable(variable);
if (resolved != null) {
ourResolved = resolved.resolve();
checkGenerics = false;
}
}
}
if (ourResolved == null) {
// Unresolved type variable, potentially nested -> never insist on exact match
exactMatch = false;
}
}
if (ourResolved == null) {
ourResolved = resolve(Object.class);
}
Class<?> otherResolved = other.toClass();
// We need an exact type match for generics
// List<CharSequence> is not assignable from List<String>
//比较的核心,第一次比较事件的Class是否一致:!ClassUtils.isAssignable(ourResolved, otherResolved)
//如果一致,判断是否具有泛型,然后比较相关的泛型。
if (exactMatch ? !ourResolved.equals(otherResolved) : !ClassUtils.isAssignable(ourResolved, otherResolved)) {
return false;
}
if (checkGenerics) {
// Recursively check each generic
ResolvableType[] ourGenerics = getGenerics();
ResolvableType[] typeGenerics = other.as(ourResolved).getGenerics();
if (ourGenerics.length != typeGenerics.length) {
return false;
}
if (matchedBefore == null) {
matchedBefore = new IdentityHashMap<>(1);
}
matchedBefore.put(this.type, other.type);
for (int i = 0; i < ourGenerics.length; i++) {
//获取事件的所有泛型,意义比较
if (!ourGenerics[i].isAssignableFrom(typeGenerics[i], matchedBefore)) {
return false;
}
}
}
return true;
}
数据类型是否匹配
@Override
public boolean supportsSourceType(@Nullable Class<?> sourceType) {
return !(this.delegate instanceof SmartApplicationListener) ||
((SmartApplicationListener) this.delegate).supportsSourceType(sourceType);
}
因为GenericApplicationListenerAdapter extends SmartApplicationListener,而SmartApplicationListener的supportesSourceType默认返回True,因此数据类型匹配永远为true。
注册监听
通过事件广播的源码跟踪,我们发现AbstractApplicationEventMulticaster.retrieveApplicationListeners方法中有如下代码:
synchronized (this.retrievalMutex) {
listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
}
非常好奇:this.defaultRetriever.applicationListeners,从哪儿来的,怎么就直接有数据了?
经过追踪,发现:org.springframework.context.support.ApplicationListenerDetector最终注册ApplicationListener。
ApplicationListenerDetector
ApplicationListenerDetector实现了BeanPostProcessor,因此可以针对每个bean,进行判断处理,并进行注册。
/**DestructionAwareBeanPostProcessor:对象销毁前的操作,从监听器中移除该监听,可以忽略
* 核心是MergedBeanDefinitionPostProcessor和BeanPostProcessor的方法。
*/
class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {
private static final Log logger = LogFactory.getLog(ApplicationListenerDetector.class);
private final transient AbstractApplicationContext applicationContext;
private final transient Map<String, Boolean> singletonNames = new ConcurrentHashMap<>(256);
public ApplicationListenerDetector(AbstractApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (ApplicationListener.class.isAssignableFrom(beanType)) {
//当前监听是否是单例
this.singletonNames.put(beanName, beanDefinition.isSingleton());
}
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof ApplicationListener) {
// potentially not detected as a listener by getBeanNamesForType retrieval
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
//只有单例才能转化为监听,这就是注册监听器的位置
// singleton bean (top-level or inner): register on the fly
this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
}
else if (Boolean.FALSE.equals(flag)) {
if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
// inner bean with other scope - can't reliably process events
logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
"but is not reachable for event multicasting by its containing ApplicationContext " +
"because it does not have singleton scope. Only top-level listener beans are allowed " +
"to be of non-singleton scope.");
}
this.singletonNames.remove(beanName);
}
}
return bean;
}
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) {
if (bean instanceof ApplicationListener) {
try {
ApplicationEventMulticaster multicaster = this.applicationContext.getApplicationEventMulticaster();
multicaster.removeApplicationListener((ApplicationListener<?>) bean);
multicaster.removeApplicationListenerBean(beanName);
}
catch (IllegalStateException ex) {
// ApplicationEventMulticaster not initialized yet - no need to remove a listener
}
}
}
@Override
public boolean requiresDestruction(Object bean) {
return (bean instanceof ApplicationListener);
}
@Override
public boolean equals(@Nullable Object other) {
return (this == other || (other instanceof ApplicationListenerDetector &&
this.applicationContext == ((ApplicationListenerDetector) other).applicationContext));
}
@Override
public int hashCode() {
return ObjectUtils.nullSafeHashCode(this.applicationContext);
}
}
addApplicationListener
@Override
public void addApplicationListener(ApplicationListener<?> listener) {
Assert.notNull(listener, "ApplicationListener must not be null");
if (this.applicationEventMulticaster != null) {
this.applicationEventMulticaster.addApplicationListener(listener);
}
this.applicationListeners.add(listener);
}
正式的加入applicationEventMulticaster中。
事件转发器
在“入口”章节,我们就提到,发布事件后,需要通过getApplicationEventMulticaster()获取转发器,然后multicastEvent,点击转发方法,默认跳转到SimpleApplicationEventMulticaster,那么什么时候注入的呢?
在AbstractApplicationContext中有字段,private ApplicationEventMulticaster applicationEventMulticaster;根据调用轨迹:org.springframework.context.support.AbstractApplicationContext#refresh中存在初始化ApplicationEventMulticaster的方法。
refresh.initApplicationEventMulticaster
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//如果已经有自定义的ApplicationMulticaster,直接使用自定义的
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
//没有,默认初始化SimpleApplicationEventMulticaster
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
因此在广播事件时,multicastEvent方法,默认跳转到:SimpleApplicationEventMulticater类。
自定义事件转发器
在SimpleApplicationEventMulticaster的multicastEvent方法中,就发现支持线程池,因此可以自定义事件转发器,配置线程池,就能实现异步处理了。
生效位置
在refresh方法中,必须在initApplicationEventMulticaster执行前,就初始化好相关的事件转发器,因此只能通过BeanFactoryPostProcessor实现相关功能。
异步事件转发器
继承SimpleApplicationEventMulticaster,通过setTaskExecutor设置线程池。
public class AsyncApplicationEventMulticaster extends SimpleApplicationEventMulticaster {
public AsyncApplicationEventMulticaster(BeanFactory beanFactory) {
super(beanFactory);
//自定义线程池,也可以通过配置信息,配置线程池
Executor executor = new ThreadPoolExecutor(1, 5,
10, TimeUnit.MINUTES,
new ArrayBlockingQueue<>(1000),
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("applicationEvent_" + t.getName());
return t;
}
}, new ThreadPoolExecutor.CallerRunsPolicy());
setTaskExecutor(executor);
}
}
注册异步事件转发器
实现BeanFactoryPostProcessor,进行异步事件转发器的注入。
public class AsyncApplicationEventMulticasterBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (!beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
//未定义相关的事件转发器
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME,
new AsyncApplicationEventMulticaster(beanFactory));
}
}
}