Spring源码分析之事件机制——观察者模式(二)
目录
获取监听器的入口方法
实际检索监听器的核心方法
监听器类型检查方法
监听器的注册过程
监听器的存储结构
过程总结
Spring源码分析之事件机制——观察者模式(一)-CSDN博客
Spring源码分析之事件机制——观察者模式(二)-CSDN博客
Spring源码分析之事件机制——观察者模式(三)-CSDN博客
这两篇文章是这个篇章的前篇和后篇,感兴趣的读者可以阅读一下,从spring源码分析观察者模式
获取监听器的入口方法
public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster {
// 存储所有监听器的集合
private final DefaultListenerRetrieverdefaultRetriever = new DefaultListenerRetriever();
// 缓存事件类型与监听器的映射关系
private final Map<ListenerCacheKey, ListenerRetriever> retrieverCache =
new ConcurrentHashMap<>(64);
protected Collection<ApplicationListener<?>> getApplicationListeners(
ApplicationEvent event, ResolvableType eventType) {
// 获取事件源和源类型
Object source = event.getSource();
Class<?> sourceType = source != null ? source.getClass() : null;
// 创建缓存key
ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
// 准备新的缓存检索器
CachedListenerRetriever newRetriever = null;
// 尝试从缓存中获取已存在的检索器
CachedListenerRetriever existingRetriever =
(CachedListenerRetriever)this.retrieverCache.get(cacheKey);
// 如果缓存中不存在,且类加载器安全(防止类加载器泄漏),则创建新的检索器
if (existingRetriever == null &&
(this.beanClassLoader == null ||
ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
(sourceType == null ||
ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
newRetriever = new CachedListenerRetriever();
// 使用CAS操作将新检索器放入缓存
existingRetriever = (CachedListenerRetriever)this.retrieverCache
.putIfAbsent(cacheKey, newRetriever);
if (existingRetriever != null) {
newRetriever = null;
}
}
// 如果存在缓存的检索器,尝试获取缓存的监听器
if (existingRetriever != null) {
Collection<ApplicationListener<?>> result =
existingRetriever.getApplicationListeners();
if (result != null) {
return result;
}
}
// 如果缓存未命中,检索匹配的监听器
return retrieveApplicationListeners(eventType, sourceType, newRetriever);
}
这个方法实现了监听器检索的缓存机制,通过缓存来提高性能,同时考虑了类加载器安全性。
实际检索监听器的核心方法
private Collection<ApplicationListener<?>> retrieveApplicationListeners(
ResolvableType eventType,
@Nullable Class<?> sourceType,
@Nullable CachedListenerRetriever retriever) {
// 存储所有匹配的监听器
List<ApplicationListener<?>> allListeners = new ArrayList();
// 如果有缓存检索器,创建过滤后的监听器集合
Set<ApplicationListener<?>> filteredListeners =
retriever != null ? new LinkedHashSet() : null;
Set<String> filteredListenerBeans =
retriever != null ? new LinkedHashSet() : null;
// 同步获取已注册的监听器和监听器Bean名称
Set<ApplicationListener<?>> listeners;
Set<String> listenerBeans;
synchronized(this.defaultRetriever) {
listeners = new LinkedHashSet(this.defaultRetriever.applicationListeners);
listenerBeans = new LinkedHashSet(this.defaultRetriever.applicationListenerBeans);
}
// 处理已实例化的监听器
for(ApplicationListener<?> listener : listeners) {
if (supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
filteredListeners.add(listener);
}
allListeners.add(listener);
}
}
// 处理监听器Bean
if (!listenerBeans.isEmpty()) {
ConfigurableBeanFactory beanFactory = getBeanFactory();
for(String listenerBeanName : listenerBeans) {
try {
// 检查Bean是否支持该事件
if (supportsEvent(beanFactory, listenerBeanName, eventType)) {
ApplicationListener<?> listener = beanFactory.getBean(
listenerBeanName, ApplicationListener.class);
// 避免重复添加
if (!allListeners.contains(listener) &&
supportsEvent(listener, eventType, sourceType)) {
// 根据Bean的作用域决定是否缓存
if (retriever != null) {
if (beanFactory.isSingleton(listenerBeanName)) {
filteredListeners.add(listener);
} else {
filteredListenerBeans.add(listenerBeanName);
}
}
allListeners.add(listener);
}
} else {
// 移除不支持的监听器
Object listener = beanFactory.getSingleton(listenerBeanName);
if (retriever != null) {
filteredListeners.remove(listener);
}
allListeners.remove(listener);
}
} catch (NoSuchBeanDefinitionException ex) {
// 忽略不存在的Bean
}
}
}
// 按照@Order注解排序
AnnotationAwareOrderComparator.sort(allListeners);
// 更新缓存
if (retriever != null) {
if (filteredListenerBeans.isEmpty()) {
retriever.applicationListeners = new LinkedHashSet(allListeners);
retriever.applicationListenerBeans = filteredListenerBeans;
} else {
retriever.applicationListeners = filteredListeners;
retriever.applicationListenerBeans = filteredListenerBeans;
}
}
return allListeners;
}
这个方法是实际检索监听器的核心实现,它处理了已实例化的监听器和尚未实例化的监听器Bean,同时考虑了Bean的作用域和缓存策略。
监听器类型检查方法
private boolean supportsEvent(
ConfigurableBeanFactory beanFactory,
String listenerBeanName,
ResolvableType eventType) {
// 获取监听器的类型
Class<?> listenerType = beanFactory.getType(listenerBeanName);
// 如果是特殊的监听器类型,直接返回true
if (listenerType != null &&
!GenericApplicationListener.class.isAssignableFrom(listenerType) &&
!SmartApplicationListener.class.isAssignableFrom(listenerType)) {
// 检查是否支持事件类型
if (!supportsEvent(listenerType, eventType)) {
return false;
}
try {
// 获取Bean定义并检查泛型类型
BeanDefinition bd = beanFactory.getMergedBeanDefinition(listenerBeanName);
ResolvableType genericEventType = bd.getResolvableType()
.as(ApplicationListener.class)
.getGeneric(new int[0]);
return genericEventType == ResolvableType.NONE ||
genericEventType.isAssignableFrom(eventType);
} catch (NoSuchBeanDefinitionException ex) {
return true;
}
}
return true;
}
这个方法负责检查监听器是否支持特定的事件类型,它考虑了泛型类型和特殊的监听器接口。整个实现展示了Spring如何高效地管理和匹配事件监听器,通过缓存机制提高性能,同时保证类型安全和正确的监听器顺序。这种实现既保证了功能的完整性,又确保了运行时的效率。
监听器的注册过程
public abstract class AbstractApplicationContext {
// 在容器刷新过程中注册监听器
protected void registerListeners() {
// 首先注册静态指定的监听器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 获取配置的监听器Bean名称
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
// 将监听器Bean名称添加到多播器
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 发布早期事件
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
}
这段代码展示了Spring如何在容器启动时注册监听器。对于像UserCacheListener这样的组件,它们会被Spring容器扫描并注册到ApplicationEventMulticaster中。
监听器的存储结构
private class CachedListenerRetriever {
@Nullable
public volatile Set<ApplicationListener<?>> applicationListeners;
@Nullable
public volatile Set<String> applicationListenerBeans;
private CachedListenerRetriever() {
}
@Nullable
public Collection<ApplicationListener<?>> getApplicationListeners() {
Set<ApplicationListener<?>> applicationListeners = this.applicationListeners;
Set<String> applicationListenerBeans = this.applicationListenerBeans;
if (applicationListeners != null && applicationListenerBeans != null) {
List<ApplicationListener<?>> allListeners = new ArrayList(applicationListeners.size() + applicationListenerBeans.size());
allListeners.addAll(applicationListeners);
if (!applicationListenerBeans.isEmpty()) {
BeanFactory beanFactory = AbstractApplicationEventMulticaster.this.getBeanFactory();
for(String listenerBeanName : applicationListenerBeans) {
try {
allListeners.add(beanFactory.getBean(listenerBeanName, ApplicationListener.class));
} catch (NoSuchBeanDefinitionException var8) {
}
}
}
if (!applicationListenerBeans.isEmpty()) {
AnnotationAwareOrderComparator.sort(allListeners);
}
return allListeners;
} else {
return null;
}
}
}
CachedListenerRetriever 其实是AbstractApplicationEventMulticaster 的静态内部类
过程总结
Spring扫描到@Component注解,创建BeanDefinition
Spring容器启动时实例化Bean
在AbstractApplicationContext.registerListeners()中注册