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

家具网站建设便宜甘肃崇信县门户网站

家具网站建设便宜,甘肃崇信县门户网站,北京做网页的公司,合肥建站书接上文#xff0c;前面在 [Spring 应用合并之路#xff08;一#xff09;#xff1a;摸石头过河]介绍了几种不成功的经验#xff0c;下面继续折腾… 四、仓库合并#xff0c;独立容器 在经历了上面的尝试#xff0c;在同事为啥不搞两个独立的容器提醒下#xff0c;…书接上文前面在 [Spring 应用合并之路一摸石头过河]介绍了几种不成功的经验下面继续折腾… 四、仓库合并独立容器 在经历了上面的尝试在同事为啥不搞两个独立的容器提醒下决定抛开 Spring Boot 内置的父子容器方案完全自己实现父子容器。 如何加载 web 项目 现在的难题只有一个如何加载 web 项目加载完成后如何持续持有 web 项目经过思考后可以创建一个 boot 项目的 Spring Bean在该 Bean 中加载并持有 web 项目的容器。由于 Spring Bean 默认是单例的并且会伴随 Spring 容器长期存活就可以保证 web 容器持久存活。结合 Spring 扩展点概览及实践 中介绍的 Spring 扩展点有两个地方可以利用 1.可以利用 ApplicationContextAware 获取 boot 容器的 ApplicationContext 实例这样就可以实现自己实现的父子容器 2.可以利用 ApplicationListener 获取 ContextRefreshedEvent 事件该事件表示容器已经完成初始化可以提供服务。在监听到该事件后来进行 web 容器的加载。 思路确定后代码实现就很简单了 package com.diguage.demo.boot.config;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.stereotype.Component;/*** author D瓜哥 · https://www.diguage.com*/ Component public class WebLoaderListener implements ApplicationContextAware,ApplicationListenerApplicationEvent {private static final Logger logger LoggerFactory.getLogger(WebLoaderListener.class);/*** 父容器加载 boot 项目*/private static ApplicationContext parentContext;/*** 子容器加载 web 项目*/private static ApplicationContext childContext;Overridepublic void setApplicationContext(ApplicationContext ctx) throws BeansException {WebLoaderListener.parentContext ctx;}Overridepublic void onApplicationEvent(ApplicationEvent event) {logger.info(receive application event: {}, event);if (event instanceof ContextRefreshedEvent) {WebLoaderListener.childContext new ClassPathXmlApplicationContext(new String[]{classpath:web/spring-cfg.xml},WebLoaderListener.parentContext);}} } 容器重复加载的问题 这次自己实现的父子容器如同设想的那样没有同名 Bean 的检查省去了很多麻烦。但是观察日志会发现 com.diguage.demo.boot.config.WebLoaderListener#onApplicationEvent 方法被两次执行也就是监听到了两次 ContextRefreshedEvent 事件导致 web 容器会被加载两次。由于项目的 RPC 服务不能重复注册第二次加载抛出异常导致启动失败。 最初怀疑是 web 容器加载了 WebLoaderListener但是跟踪代码没有发现 childContext 容器中有 WebLoaderListener 的相关 Bean。 昨天做了个小实验又调试了一下 Spring 的源代码发现了其中的奥秘。直接贴代码吧 SPRING/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java /*** Publish the given event to all listeners.* pThis is the internal delegate that all other {code publishEvent}* methods refer to. It is not meant to be called directly but rather serves* as a propagation mechanism between application contexts in a hierarchy,* potentially overridden in subclasses for a custom propagation arrangement.* param event the event to publish (may be an {link ApplicationEvent}* or a payload object to be turned into a {link PayloadApplicationEvent})* param typeHint the resolved event type, if known.* The implementation of this method also tolerates a payload type hint for* a payload object to be turned into a {link PayloadApplicationEvent}.* However, the recommended way is to construct an actual event object via* {link PayloadApplicationEvent#PayloadApplicationEvent(Object, Object, ResolvableType)}* instead for such scenarios.* since 4.2* see ApplicationEventMulticaster#multicastEvent(ApplicationEvent, ResolvableType)*/ protected void publishEvent(Object event, Nullable ResolvableType typeHint) {Assert.notNull(event, Event must not be null);ResolvableType eventType null;// Decorate event as an ApplicationEvent if necessaryApplicationEvent applicationEvent;if (event instanceof ApplicationEvent applEvent) {applicationEvent applEvent;eventType typeHint;}else {ResolvableType payloadType null;if (typeHint ! null ApplicationEvent.class.isAssignableFrom(typeHint.toClass())) {eventType typeHint;}else {payloadType typeHint;}applicationEvent new PayloadApplicationEvent(this, event, payloadType);}// Determine event type only once (for multicast and parent publish)if (eventType null) {eventType ResolvableType.forInstance(applicationEvent);if (typeHint null) {typeHint eventType;}}// Multicast right now if possible - or lazily once the multicaster is initializedif (this.earlyApplicationEvents ! null) {this.earlyApplicationEvents.add(applicationEvent);}else if (this.applicationEventMulticaster ! null) {this.applicationEventMulticaster.multicastEvent(applicationEvent, eventType);}// Publish event via parent context as well...// 如果有父容器则也将事件发布给父容器。if (this.parent ! null) {if (this.parent instanceof AbstractApplicationContext abstractApplicationContext) {abstractApplicationContext.publishEvent(event, typeHint);}else {this.parent.publishEvent(event);}} } 在 publishEvent 方法的最后如果父容器不为 null 的情况下则也会向父容器广播容器的相关事件。 看到这里就清楚了不是 web 容器持有了 WebLoaderListener 这个 Bean而是 web 容器主动向父容器广播了 ContextRefreshedEvent 事件。 容器销毁 除了上述问题还有一个问题需要思考如何销毁 web 容器如果不能销毁容器会有一些意想不到的问题。比如注册中心的 RPC 提供方不能及时销毁等等。 这里的解决方案也比较简单同样基于事件监听Spring 容器销毁会有 ContextClosedEvent 事件在 WebLoaderListener 中监听该事件然后调用 AbstractApplicationContext#close 方法就可以完成 Spring 容器的销毁工作。 父子容器加载及销毁 结合上面的所有论述完整的代码如下 package com.diguage.demo.boot.config;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextClosedEvent; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.stereotype.Component;import java.util.Objects;/*** 基于事件监听的 web 项目加载器** author D瓜哥 · https://www.diguage.com*/ Component public class WebLoaderListener implements ApplicationContextAware,ApplicationListenerApplicationEvent {private static final Logger logger LoggerFactory.getLogger(WebLoaderListener.class);/*** 父容器加载 boot 项目*/private static ApplicationContext parentContext;/*** 子容器加载 web 项目*/private static ClassPathXmlApplicationContext childContext;Overridepublic void setApplicationContext(ApplicationContext ctx) throws BeansException {WebLoaderListener.parentContext ctx;}/*** 事件监听** author D瓜哥 · https://www.diguage.com*/Overridepublic void onApplicationEvent(ApplicationEvent event) {logger.info(receive application event: {}, event);if (event instanceof ContextRefreshedEvent refreshedEvent) {ApplicationContext context refreshedEvent.getApplicationContext();if (Objects.equals(WebLoaderListener.parentContext, context)) {// 加载 web 容器WebLoaderListener.childContext new ClassPathXmlApplicationContext(new String[]{classpath:web/spring-cfg.xml},WebLoaderListener.parentContext);}} else if (event instanceof ContextClosedEvent) {// 处理容器销毁事件if (Objects.nonNull(WebLoaderListener.childContext)) {synchronized (WebLoaderListener.class) {if (Objects.nonNull(WebLoaderListener.childContext)) {AbstractApplicationContext ctx WebLoaderListener.childContext;WebLoaderListener.childContext null;ctx.close();}}}}} } 五、参考资料 1.Spring 扩展点概览及实践 - 地瓜哥博客网 2.Context Hierarchy with the Spring Boot Fluent Builder API 3.How to revert initial git commit? 作者京东科技 李君 来源京东云开发者社区 转载请注明来源
http://www.zqtcl.cn/news/648553/

相关文章:

  • 成都销售型网站长春财经学院多大
  • 手机自己制作表白网站app项目网络计划图怎么画
  • 品牌网站如何做seo浏览器正能量网址
  • 开封做网站哪家好网页设计制作网站大一素材
  • 河南网站域名备案莱芜新闻电视台节目表
  • 长春网站建设新格做天猫还是做网站推广
  • 新网站建设的感想安阳区号是什么
  • 余姚市城乡建设局网站wordpress 预览插件
  • 游戏开发和网站开发wordpress foreign trade
  • 网站设计 原型图html购物网站模板
  • 谷歌网站推广报价国产搜什么关键词最好看
  • 婚礼网站有哪些个人做网站需要什么条件
  • 深圳企业网站seo人才招聘网站建设
  • 谷歌下载seo是什么软件
  • 个人网站设计分析小程序在线制作平台
  • 网站开发 一般用什么语言vi视觉设计案例
  • 微信公众平台官方网官网seo优化找哪家做
  • 简约 网站模板网站目录链接怎么做
  • 国内地铁建设公司网站大连做网站外包
  • 微网站营销是什么网站图片上传代码
  • 外包公司做网站多少用vs做的网站怎么打开
  • 兴义城乡建设部网站企业服务器配置方案
  • 淘宝客网站根目录wordpress调用导航代码
  • 海外免费网站推广网站开发项目报告书
  • 大气的金融网站深圳专门做兼职的网站
  • 最新网站备案四平网站公司
  • 济宁恒德建设有限公司网站互联网营销师报名入口
  • 做灯饰的企业都会在哪些网站网站排名恢复
  • 互联网公司网站建设价格跨境支付互联互通
  • 杭州 高端网站 开发宜昌建设网站公司