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

没有网站怎样做搜索引擎推广在线代理网页代理

没有网站怎样做搜索引擎推广,在线代理网页代理,在线网页代理浏览器,八年级信息技术网页制作spring事件监听机制离不开容器IOC特性提供的支持#xff0c;比如容器会自动创建事件发布器#xff0c;自动识别用户注册的监听器并进行管理#xff0c;在特定的事件发布后会找到对应的事件监听器并对其监听方法进行回调。Spring帮助用户屏蔽了关于事件监听机制背后的很多细节…spring事件监听机制离不开容器IOC特性提供的支持比如容器会自动创建事件发布器自动识别用户注册的监听器并进行管理在特定的事件发布后会找到对应的事件监听器并对其监听方法进行回调。Spring帮助用户屏蔽了关于事件监听机制背后的很多细节使用户可以专注于业务层面进行自定义事件开发。然而我们对内部的实现还是有一些疑问比如 • 事件发布器ApplicationEventMulticaster是何时被初始化的初始化过程中都做了什么 • 注册事件监听器的过程是怎样的容器怎么识别出它们并进行管理? • 容器发布事件的流程是怎样的它如何根据发布的事件找到对应的事件监听器事件和由该事件触发的监听器之间的匹配规则是怎样的 初始化事件发布器流程 真正的事件发布器是ApplicationEventMulticaster它定义在AbstractApplicationContext中并在ApplicationContext容器启动的时候进行初始化。在容器启动的refrsh()方法中可以找到初始化事件发布器的入口方法如下图所示 /*** Initialize the ApplicationEventMulticaster.* Uses SimpleApplicationEventMulticaster if none defined in the context.* see org.springframework.context.event.SimpleApplicationEventMulticaster*/protected void initApplicationEventMulticaster() {ConfigurableListableBeanFactory beanFactory getBeanFactory();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 {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() ]);}}} 这里会根据核心容器beanFactory中是否有id为applicationEventMulticaster的bean分两种情况 1容器中已有id为applicationEventMulticaster的bean直接从容器缓存获取或是创建该bean实例,并交由成员变量applicationEventMulticaster保存。当用户自定义了事件发布器并向容器注册时会执行该流程。 2容器中不存在applicationEventMulticaster的bean这是容器默认的执行流程,会创建一个SimpleApplicationEventMulticaster其仅在实现事件发布器基本功能(管理事件监听器以及发布容器事件)的前提下增加了可以设置任务执行器Executor和错误处理器ErrorHandler的功能当设置Executor为线程池时,则会以异步的方式对事件监听器进行回调,而ErrorHandler允许我们在回调方法执行错误时进行自定义处理。默认情况下这两个变量都为null。 之后会调用beanFactory.registerSingleton方法将创建的SimpleApplicationEventMulticaster实例注册为容器的单实例bean。 初始化事件发布器总结一句话由容器实例化用户自定义的事件发布器或者由容器帮我们创建一个简单的事件发布器并交由容器管理。 注册事件监听器流程 注册事件监听器的流程在初始化事件发布器之后如下图所示 /*** Add beans that implement ApplicationListener as listeners.* Doesnt affect other listeners, which can be added without being beans.*/protected void registerListeners() {// 首先注册静态指定的监听器。for (ApplicationListener? listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);}// 不要在这里初始化FactoryBeans我们需要保留所有常规Bean// 未初始化以允许后处理器应用于它们String[] listenerBeanNames getBeanNamesForType(ApplicationListener.class, true, false);for (String listenerBeanName : listenerBeanNames) {getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);}// 发布早期应用程序事件SetApplicationEvent earlyEventsToProcess this.earlyApplicationEvents;this.earlyApplicationEvents null;if (earlyEventsToProcess ! null) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);}}} 容器事件发布流程 org.springframework.context.support.AbstractApplicationContext#publishEvent(java.lang.Object, ResolvableType) 将给定事件发布给所有侦听器 前面说在启动的时候如果没有一个beanName叫做applicationEventMulticaster的ApplicationEventMulticaster那使用的就是SimpleApplicationEventMulticaster该组件会在容器启动时被自动创建并以单例的形式存在管理了所有的事件监听器并提供针对所有容器内事件的发布功能。 org.springframework.context.event.SimpleApplicationEventMulticaster#multicastEvent(ApplicationEvent, ResolvableType) Override public void multicastEvent(final ApplicationEvent event, Nullable ResolvableType eventType) { //获取事件类型 ResolvableType type (eventType ! null ? eventType : resolveDefaultEventType(event)); //获取事件发布器内的任务执行器,默认该方法返回null Executor executor getTaskExecutor(); //遍历所有和事件匹配的事件监听器 for (ApplicationListener? listener : getApplicationListeners(event, type)) { if (executor ! null) { //异步回调监听方法 executor.execute(() - invokeListener(listener, event)); } else { //同步回调监听方法 invokeListener(listener, event); } } }如何根据事件类型找到匹配的所有事件监听器 org.springframework.context.event.AbstractApplicationEventMulticaster#getApplicationListeners(ApplicationEvent, ResolvableType) /*** Return a Collection of ApplicationListeners matching the given* event type. Non-matching listeners get excluded early.* param event the event to be propagated. Allows for excluding* non-matching listeners early, based on cached matching information.* param eventType the event type* return a Collection of ApplicationListeners* see org.springframework.context.ApplicationListener*/protected CollectionApplicationListener? getApplicationListeners(ApplicationEvent event, ResolvableType eventType) {// 获取事件中的事件源对象Object source event.getSource();// 获取事件源类型Class? sourceType (source ! null ? source.getClass() : null);// 以事件类型和事件源类型为参数构建一个cacheKey 用于从缓存map中获取与之匹配的监听器列表ListenerCacheKey cacheKey new ListenerCacheKey(eventType, sourceType);// 根据cacheKey从缓存中获取CachedListenerRetrieverListenerRetriever 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 ListenerRetrieversynchronized (this.retrievalMutex) {retriever this.retrieverCache.get(cacheKey);if (retriever ! null) {return retriever.getApplicationListeners();}retriever new ListenerRetriever(true);// 不存在就检索给定事件和源类型的应用程序侦听器并放到缓存CollectionApplicationListener? listeners retrieveApplicationListeners(eventType, sourceType, retriever);this.retrieverCache.put(cacheKey, retriever);return listeners;}}else {// No ListenerRetriever caching - no synchronization necessaryreturn retrieveApplicationListeners(eventType, sourceType, null);}} 如果事件时第一次发布会遍历所有的事件监听器并根据事件类型和事件源类型进行匹配 org.springframework.context.event.AbstractApplicationEventMulticaster#retrieveApplicationListeners /*** Actually retrieve the application listeners for the given event and source type.* param eventType the event type* param sourceType the event source type* param retriever the ListenerRetriever, if supposed to populate one (for caching purposes)* return the pre-filtered list of application listeners for the given event and source type*/private CollectionApplicationListener? retrieveApplicationListeners(ResolvableType eventType, Nullable Class? sourceType, Nullable ListenerRetriever retriever) {// 存放监听器的列表ListApplicationListener? allListeners new ArrayList();SetApplicationListener? listeners;SetString listenerBeans;synchronized (this.retrievalMutex) {listeners new LinkedHashSet(this.defaultRetriever.applicationListeners);listenerBeans new LinkedHashSet(this.defaultRetriever.applicationListenerBeans);}// 添加以编程方式注册的侦听器// 包括来自ApplicationListenerDetector的侦听器单例bean和内部bean。for (ApplicationListener? listener : listeners) {if (supportsEvent(listener, eventType, sourceType)) {if (retriever ! null) {retriever.applicationListeners.add(listener);}allListeners.add(listener);}}// 按bean名称添加侦听器这可能与上面通过编程注册的侦听器重叠// 但这里可能有额外的元数据。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 {// 删除最初来自ApplicationListenerDetector的不匹配侦听器// 可能会被上面额外的BeanDefinition元数据例如工厂方法泛型排除。Object listener beanFactory.getSingleton(listenerBeanName);if (retriever ! null) {retriever.applicationListeners.remove(listener);}allListeners.remove(listener);}}catch (NoSuchBeanDefinitionException ex) {// 单一侦听器实例没有支持bean定义消失-可能在销毁阶段中期}}}//对匹配的监听器列表进行排序AnnotationAwareOrderComparator.sort(allListeners);if (retriever ! null retriever.applicationListenerBeans.isEmpty()) {retriever.applicationListeners.clear();retriever.applicationListeners.addAll(allListeners);}return allListeners;} 容器事件发布的整个流程可以总结如下
http://www.huolong8.cn/news/10069/

相关文章:

  • 北京网站开发公司一网天行石家庄最新事件
  • 怎样让网站排名优化工做动画网站
  • 设计好看的企业网站c2c网站开发
  • 360免费建站系统设置本机外网ip做网站
  • 专业商城网站设计制作网页设计与制作的三个阶段
  • 设计logo网站免费奇米网站建设作业多少钱
  • 网站建设开发的规划流程网站发展趋势
  • 做电影资源网站有哪些电影网站怎么建设
  • 合肥做网站优化哪家好贵阳网站建设黔搜
  • 网站建设图片怎么加水印宁德东侨建设局网站
  • 长沙网站推广 下拉通推广银川网站建设怎么样
  • 济南建网站公养殖业网站模板
  • 厦门建站比较好的公司关于网站建设的问题
  • 四川省微信网站建设公wordpress alipay插件
  • 企业网站建设专业济南seo的排名优化
  • 网站建设合同定义做企业网站 签合同要注意什么
  • 营销网站与传统网站的区别西安网站有哪些手续费
  • 江西哪里有做电商网站的公司网络营销现状分析
  • 免费的网站推广平台表白网站生成器
  • 建信建设投资有限公司网站在线阅读小说网站怎么做
  • 北京建设网站制作如何注册wordpress
  • 照片分享网站模板下载做网站弄关键词多少钱
  • 无锡正规网站seo公司wordpress 产品链接
  • 公司网站设计费计入什么科目品牌建设体系
  • 开原铁岭网站建设股票网站怎么做动态表格
  • 网站建设亿金手指花总12wordpress用户前台
  • seo优化网站教程百度市场营销产品推广策划方案
  • 建设机械网站方案如何更改wordpress后台登陆密码
  • 网站开发的论文题目桂林人生活论坛
  • 杭州网站建设费用价格广州网站建设定制哪家口碑好