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

b2c网站功能需求石家庄网络营销

b2c网站功能需求,石家庄网络营销,凡科商城app下载,税务网站怎样查询建设项目目录 获取监听器的入口方法 实际检索监听器的核心方法 监听器类型检查方法 监听器的注册过程 监听器的存储结构 过程总结 Spring源码分析之事件机制——观察者模式(一)-CSDN博客 Spring源码分析之事件机制——观察者模式(二&#xff…

目录

获取监听器的入口方法

实际检索监听器的核心方法

监听器类型检查方法 

监听器的注册过程

监听器的存储结构

过程总结


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;// 创建缓存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) {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);}}// 处理监听器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);}// 发布早期事件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 {@Nullablepublic volatile Set<ApplicationListener<?>> applicationListeners;@Nullablepublic volatile Set<String> applicationListenerBeans;private CachedListenerRetriever() {}@Nullablepublic 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()中注册

http://www.tj-hxxt.cn/news/89915.html

相关文章:

  • 网站建设预算表网络营销外包推广
  • 漳州做网站配博大钱少a杭州百度快速排名提升
  • 性价比高的做网站公司关键词seo排名优化软件
  • 四川省住房和城乡建设厅网站是多少上海百度竞价点击软件
  • 住建培训网站广州引流推广公司
  • 聊天直播软件开发宁波seo在线优化方案
  • 网站推广策划的流程兰州疫情最新情况
  • 三合一网站建设永久免费域名申请
  • 网站开发实训报告网络推广属于什么行业
  • 做网站挣钱快吗百度问答平台
  • Wordpress嵌套其他网站百度一下生活更好
  • 香港网站备案查询如何解决网站只收录首页的一些办法
  • 二维码转链接百度seo推广计划类型包含
  • 白石龙做网站广州疫情已经达峰
  • 建设网站合同范本抖音seo教程
  • 珠海响应式网站建设网络营销的方式
  • 九龙坡网站建设多少钱深圳网站设计专家乐云seo
  • 网站的优化公司广州新一期lpr
  • 医学分类手机网站模版搜索引擎优化网站排名
  • 好看的网站设计公司百度公司官网首页
  • 请人做网站注意事项介绍网络营销
  • 发帖那个网站好 做装修的刚刚济南发通知
  • 网站建设中故障分类和排除方法google中文搜索引擎入口
  • 武汉网站seo公司技术营销方案网站
  • 万由nas做网站怎么开发一款app软件
  • 新乡做新网站上海做seo的公司
  • WordPress建站去掉后缀杭州优化外包哪里好
  • 专门做ppt的网站名称网络营销网络推广
  • 做毕业论文设计的网站千锋教育培训机构就业率
  • 网站编辑的岗位职责怎么样建网站