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

建设一个自己的网站网络工程是学啥的

建设一个自己的网站,网络工程是学啥的,网站建设 深圳宝安,wordpress换鼠标样式书接上文#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/963746/

相关文章:

  • 机械网站建设中心莱芜论坛莱芜都市网
  • 58同城类似的网站怎么做seo做的比较好的公司
  • 厦门网站建设培训学校网站程序定制开发流程
  • 宣传旅游网站建设的观点是什么资阳网站建设方案
  • ui设计与网站建设怎么建设一个手机网站
  • 网站建设加推广优化网站移动端开发公司
  • 猪八戒网站开发电子商务公司取名字参考大全
  • 酒泉手机网站建设大连网站如何制作
  • 做网站点子免费做简历的软件网站
  • 刘涛做代言的那个网站设计与制作
  • 专业网站建站星辰wordpress主题
  • 淄博个人网站建设天津网站制作机玩法部
  • 帮人做图挣外快的网站seo优化教学视频
  • 做房产中介需要有内部网站吗烟台开发区网站建设
  • 网站资质优化网站备案密码使用
  • 廊坊营销网站团队网站推广报告
  • 商品网站模板多语言企业网站模板
  • 佛山网页制作设计东莞seo推广机构帖子
  • 公司网站开发费用如何入账网站开发与设计实训总结两千字
  • 生物网站模板在线crm厂商
  • 在线制作动画网站ps切图做网站
  • 西安企业网站建设公司虚拟主机可以做视频网站嘛
  • 做淘客网站用什么程序今天杭州新闻最新消息
  • 东莞专业建网站网站制作方案相信乐云seo
  • 网站分页符素材怎么解决
  • 行远金华网站建设公司合肥公司做网站
  • 餐厅类网站模板中国电建市政建设集团有限公司网站
  • 格力网站建设首页六盘水遵义网站建设怎么做
  • 建设工程企业资质工作网站创建网站怎么赚钱的
  • 三水网站建设流感吃什么药最好