商城网站网络公司,软件产品开发流程8个步骤,wordpress可以干啥,官方商城下载目录
获取监听器的入口方法
实际检索监听器的核心方法
监听器类型检查方法
监听器的注册过程
监听器的存储结构
过程总结 Spring源码分析之事件机制——观察者模式#xff08;一#xff09;-CSDN博客
Spring源码分析之事件机制——观察者模式#xff08;二#xff…
目录
获取监听器的入口方法
实际检索监听器的核心方法
监听器类型检查方法
监听器的注册过程
监听器的存储结构
过程总结 Spring源码分析之事件机制——观察者模式一-CSDN博客
Spring源码分析之事件机制——观察者模式二-CSDN博客
Spring源码分析之事件机制——观察者模式三-CSDN博客
这两篇文章是这个篇章的前篇和后篇感兴趣的读者可以阅读一下从spring源码分析观察者模式
获取监听器的入口方法 public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster {// 存储所有监听器的集合private final DefaultListenerRetrieverdefaultRetriever new DefaultListenerRetriever();// 缓存事件类型与监听器的映射关系private final MapListenerCacheKey, ListenerRetriever retrieverCache new ConcurrentHashMap(64);protected CollectionApplicationListener? getApplicationListeners(ApplicationEvent event, ResolvableType eventType) {// 获取事件源和源类型Object source event.getSource();Class? sourceType source ! null ? source.getClass() : null;// 创建缓存keyListenerCacheKey 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) {CollectionApplicationListener? result existingRetriever.getApplicationListeners();if (result ! null) {return result;}}// 如果缓存未命中检索匹配的监听器return retrieveApplicationListeners(eventType, sourceType, newRetriever);
}
这个方法实现了监听器检索的缓存机制通过缓存来提高性能同时考虑了类加载器安全性。
实际检索监听器的核心方法
private CollectionApplicationListener? retrieveApplicationListeners(ResolvableType eventType, Nullable Class? sourceType, Nullable CachedListenerRetriever retriever) {// 存储所有匹配的监听器ListApplicationListener? allListeners new ArrayList();// 如果有缓存检索器创建过滤后的监听器集合SetApplicationListener? filteredListeners retriever ! null ? new LinkedHashSet() : null;SetString filteredListenerBeans retriever ! null ? new LinkedHashSet() : null;// 同步获取已注册的监听器和监听器Bean名称SetApplicationListener? listeners;SetString 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);}}// 处理监听器Beanif (!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);// 如果是特殊的监听器类型直接返回trueif (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);}// 发布早期事件SetApplicationEvent earlyEventsToProcess this.earlyApplicationEvents;this.earlyApplicationEvents null;if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);}}}
}
这段代码展示了Spring如何在容器启动时注册监听器。对于像UserCacheListener这样的组件它们会被Spring容器扫描并注册到ApplicationEventMulticaster中。 监听器的存储结构 private class CachedListenerRetriever {Nullablepublic volatile SetApplicationListener? applicationListeners;Nullablepublic volatile SetString applicationListenerBeans;private CachedListenerRetriever() {}Nullablepublic CollectionApplicationListener? getApplicationListeners() {SetApplicationListener? applicationListeners this.applicationListeners;SetString applicationListenerBeans this.applicationListenerBeans;if (applicationListeners ! null applicationListenerBeans ! null) {ListApplicationListener? 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()中注册