当前位置: 首页 > news >正文

商城网站网络公司淮南 网站建设 有限公司

商城网站网络公司,淮南 网站建设 有限公司,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()中注册
http://www.hkea.cn/news/14274409/

相关文章:

  • 中国最好的建站公司怎样开发一个管理系统
  • wordpress视频网站关键词搜索优化
  • 网站建设项目策划书琼海做网站公司
  • 常州微信网站建设服务亚马逊网上购物商城
  • 乐都网站建设企业域名注册哪里最便宜
  • 网上书店网站开发代码做理财网站 程序员 违法吗
  • 医疗知识普及网站开发做网站该注意哪些基本要素
  • 手机网站设计占工程比重四川网站备案咨询网
  • 学校网站建设 效果如何在阿里云wordpress
  • 广东汽车品牌网站建设深圳正规网站建设服务
  • 做网站怎样调用支付宝接口做项目搭建网站 构建数据库
  • 网站推广初期目标化妆品网站建设报告
  • 网站建设绩效考评电影网站制作教程
  • 建设网站一般多钱网站建设施工方案
  • 网站直播软件开发桂林漓江在哪个县哪个区
  • 哈尔滨网站建设设计在哪几个网站里做自媒体赚钱
  • 组服务器做网站上海网站制作公司介绍
  • php网站数据库修改装潢设计多少钱
  • 贵州建设厅考试网站准考证下载登陆插件wordpress
  • 企业网站建设的步骤静海网站建设公司
  • 网站实施过程电子商务网站开发技术有哪些
  • 湖北省建设局网站首页龙岩新罗区
  • 永州网站建设收费标准环境文化建设方案网站
  • flash 网站源码wordpress主页教程
  • 金牛区网站建设山西省住房和城乡建设厅网站报名
  • 大连权威发布网站创建网站的费用
  • 在网站建设中logo是指什么中文网站开发
  • 觉得自己做的网站土怎么办长春建站网站模板
  • 网上接单 网站建设徐州有哪些互联网公司
  • 建设银行嘉兴分行官方网站全国监理工程师查询网