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

做软件公司网站湖北省建设厅乡镇污水官方网站

做软件公司网站,湖北省建设厅乡镇污水官方网站,新手站长如何购买虚拟主机做网站,企业网站怎么搜索优化文章目录 前情提要发散探索从management.port开始确定否需要开启额外端口额外端口是如何开启的ManagementContextFactory的故事从哪儿来创建过程 management 相关API如何被注册 小结 前情提要 最近遇到一个需求#xff0c;在单个服务进程上开启多网络端口#xff0c;将API的… 文章目录 前情提要发散探索从management.port开始确定否需要开启额外端口额外端口是如何开启的ManagementContextFactory的故事从哪儿来创建过程 management 相关API如何被注册 小结 前情提要 最近遇到一个需求在单个服务进程上开启多网络端口将API的访问通过端口强行隔离开。 发散探索 SpringBoot自带的多端口配置server.port和management.port将常规的API与管理相关API通过端口拆分开1中的端口是基于HTTP/1.1通信的如果需要基于HTTP/2.0如gRPC)又会有些差别一般一个进程内SpringApplication对象只有1个理论上搞多个自然就能开启多个端口略显粗暴 本着探索的态度我会逐个探讨上述3个方向本文先关注在方向1上。如果你有更NB的问题或者建议欢迎评论区留言。 从management.port开始 配置生效依赖SpringBoot的AutoConfiguration机制management相关配置体现在ManagementContextAutoConfiguration中完成ManagementContext的配置其中涉及的问题如下。 确定否需要开启额外端口 ConditionalOnManagementPort决定了是否开启新端口该注解声明如下 Retention(RetentionPolicy.RUNTIME) Target({ ElementType.TYPE, ElementType.METHOD }) Documented Conditional(OnManagementPortCondition.class) public interface ConditionalOnManagementPort {/*** The {link ManagementPortType} to match.* return the port type*/ManagementPortType value();}其依赖的OnManagementPortCondition会在配置过程中被处理处理概要过程如下 基于当前的Environment决定实际的ManagementPortType获得当前注解中value对应的设定ManagementPortType;基于1和2决定被其注解的bean是否初始化ManagementPortType的定义如下 public enum ManagementPortType {/*** The management port has been disabled.*/DISABLED,/*** The management port is the same as the server port.*/SAME,/*** The management port and server port are different.*/DIFFERENT;/*** Look at the given environment to determine if the {link ManagementPortType} is* {link #DISABLED}, {link #SAME} or {link #DIFFERENT}.* param environment the Spring environment* return {link #DISABLED} if {code management.server.port} is set to a negative* value, {link #SAME} if {code management.server.port} is not specified or equal to* {code server.port} and {link #DIFFERENT} otherwise.* since 2.1.4*/public static ManagementPortType get(Environment environment) {Integer managementPort getPortProperty(environment, management.server.);if (managementPort ! null managementPort 0) {return DISABLED;}Integer serverPort getPortProperty(environment, server.);return ((managementPort null || (serverPort null managementPort.equals(8080))|| (managementPort ! 0 managementPort.equals(serverPort))) ? SAME : DIFFERENT);}private static Integer getPortProperty(Environment environment, String prefix) {return environment.getProperty(prefix port, Integer.class);}}额外端口是如何开启的 到这里我们可以回到ManagementContextAutoConfiguration针对性地关注ConditionalOnManagementPort(ManagementPortType.DIFFERENT)相关类, 也就是下面这段 Configuration(proxyBeanMethods false)ConditionalOnManagementPort(ManagementPortType.DIFFERENT)static class DifferentManagementContextConfiguration implements ApplicationListenerWebServerInitializedEvent {private final ApplicationContext applicationContext;private final ManagementContextFactory managementContextFactory;DifferentManagementContextConfiguration(ApplicationContext applicationContext,ManagementContextFactory managementContextFactory) {this.applicationContext applicationContext;this.managementContextFactory managementContextFactory;}Overridepublic void onApplicationEvent(WebServerInitializedEvent event) {if (event.getApplicationContext().equals(this.applicationContext)) {ConfigurableWebServerApplicationContext managementContext this.managementContextFactory.createManagementContext(this.applicationContext,EnableChildManagementContextConfiguration.class,PropertyPlaceholderAutoConfiguration.class);if (isLazyInitialization()) {managementContext.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());}managementContext.setServerNamespace(management);managementContext.setId(this.applicationContext.getId() :management);setClassLoaderIfPossible(managementContext);CloseManagementContextListener.addIfPossible(this.applicationContext, managementContext);managementContext.refresh();}}protected boolean isLazyInitialization() {AbstractApplicationContext context (AbstractApplicationContext) this.applicationContext;ListBeanFactoryPostProcessor postProcessors context.getBeanFactoryPostProcessors();return postProcessors.stream().anyMatch(LazyInitializationBeanFactoryPostProcessor.class::isInstance);}private void setClassLoaderIfPossible(ConfigurableApplicationContext child) {if (child instanceof DefaultResourceLoader) {((DefaultResourceLoader) child).setClassLoader(this.applicationContext.getClassLoader());}}}从中我们可以发现几个点 ManagementContext是在主WebApplicationContext发布事件WebServerInitializedEvent后开始初始化;ManagementContext全新的ConfigurableWebServerApplicationContext这意味着最终启动后内存中存在至少两个ApplicationContext如果说开启两个SpringApplication对象是表象的话那么创建两个WebApplicationContext应该说就是底层的本质了整个处理过程就是创建ConfigurableWebServerApplicationContext后续做必要的配置最后refresh。如果你分析过SpringApplication.run()那想必你看到了熟悉的味道。 ManagementContextFactory的故事 从哪儿来 对应的子类有两个ReactiveManagementContextFactory和ServletManagementContextFactory具体初始化则由xxxManagementContextFactoryAutoConfiguration影响更进一步的细节藏在 ConditionalOnWebApplication(typexxx)中。 创建过程 以ReactiveManagementContextFactory为例 Overridepublic ConfigurableWebServerApplicationContext createManagementContext(ApplicationContext parent,Class?... configClasses) {// 复用EnvironmentEnvironment parentEnvironment parent.getEnvironment();ConfigurableEnvironment childEnvironment ApplicationContextFactory.DEFAULT.createEnvironment(WebApplicationType.REACTIVE);if (parentEnvironment instanceof ConfigurableEnvironment) {// 复用ConversionServicechildEnvironment.setConversionService(((ConfigurableEnvironment) parentEnvironment).getConversionService());}AnnotationConfigReactiveWebServerApplicationContext child new AnnotationConfigReactiveWebServerApplicationContext();child.setEnvironment(childEnvironment);// 这里可以看到最终会是parent和child关系child.setParent(parent);/* 这里以编程的方式完成BeanDefinition注册, 这里的configClass {EnableChildManagementContextConfiguration.class,PropertyPlaceholderAutoConfiguration.class} */Class?[] combinedClasses ObjectUtils.addObjectToArray(configClasses,ReactiveWebServerFactoryAutoConfiguration.class);child.register(combinedClasses);// 最后保持parent和child的WebFactory一致, 直接复用parent的BeanDefinitionregisterReactiveWebServerFactory(parent, child);return child;}management 相关API如何被注册 经过前面一波分析我们已经看到了创建ApplicationContext注册必要的Class而后refresh整个容器就要启动但没有看到management相关API其实就藏在EnableChildManagementContextConfiguration.class这里, 从这里出发最终找到配置文件ManagementContextConfiguration.imports链路如下 EnableManagementContext - ManagementContextConfigurationImportSelector - META-INFO/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.importsManagementContextConfiguration.imports的内容如下 org.springframework.boot.actuate.autoconfigure.endpoint.web.ServletEndpointManagementContextConfiguration org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive.WebFluxEndpointManagementContextConfiguration org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey.JerseyWebEndpointManagementContextConfiguration org.springframework.boot.actuate.autoconfigure.security.servlet.SecurityRequestMatchersManagementContextConfiguration org.springframework.boot.actuate.autoconfigure.web.jersey.JerseySameManagementContextConfiguration org.springframework.boot.actuate.autoconfigure.web.jersey.JerseyChildManagementContextConfiguration org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementChildContextConfiguration org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementChildContextConfiguration org.springframework.boot.actuate.autoconfigure.web.servlet.WebMvcEndpointChildContextConfiguration这些Configuration最终受如下2个注解的解决决定是否初始化 ManagementContextConfiguration(value ManagementContextType.xxx, proxyBeanMethods false) ConditionalOnWebApplication(type Type.xxx) 最终不同的EndPoint由不同的EndPointDiscover对整个ApplicationContext中的类进行扫描并提取出来组装为EndPointHandlerMapping。 到这里可以解释一个现象就是在manage端口上无法访问到应用端口上的API因为两者各自关联了一个独立的HandlerMapping。虽然通常child context可以访问到parent context中的所有bean实例但是各自可见的API被各自的RequestHandlerMapping限制而隔离。 小结 以上是针对mangement API开放独立端口的探究从中有几个点值得借鉴 独立的ApplicationContext可以作为资源隔离的一种方式同时又不完全失去与parent的联系条件初始化在SpringBoot自动配置中的广泛应用WebApplicationContext与ApplicationContext的区别在于WebServerFactory是否存在以及RequestHandlerMapping必要的注解识别有了这点发现做API隔离可用的方案也会更加丰富 后续会对另外2种实现方式做探讨感谢你的阅读。
http://www.dnsts.com.cn/news/99319.html

相关文章:

  • wordpress 插件卸载标题优化seo
  • 佛山营销型建设网站做网站需要找人优化吗
  • 建站的公司网站建设珠海
  • 网站登录超时怎么解决丰都网站建设价格
  • 事业单位网站建设费入什么科目霍尔果斯网站建设
  • 网站优化说明13岁找对象去哪个软件
  • ps网站设计概述wordpress 搬家
  • 政协网站信息化建设的作用阿里云网站开发工具
  • 学校如何重视校园网站建设海口市龙华区核酸检测
  • 高端网站建设设计湖北手机网站建设
  • 移动网站建设专业论文普通网站跟营销型网站的对比
  • saas云建站平台源码济南住建局官方网站
  • 建站平台绑定域名在百度做推广送网站好吗
  • 太湖云建站网站建设网站内容 优化
  • 专业网站建设首选公司长春火车站咨询电话号码是多少
  • 网站怎样做wap端做编程的网站有哪些内容
  • 梅州做网站网站建设验收总结讲话
  • 广州营销型网站建设招聘网站销售怎么做
  • 腾讯云做网站步骤视觉设计的网站和app
  • 不想用原来的网站模板了就用小偷工具采集了一个可是怎么替换wordpress可以和微信公众号对接
  • 深圳的设计网站公司应用asp做网站
  • vs网站开发建表怎么肩啊wordpress 热门主题
  • 公司网站上传图库上海网站建设-中国互联
  • 用织梦做网站快吗小叮当网站建设
  • 怎么做网站导流生意it培训机构哪些比较好
  • 做网站怎么防止被黑沧州建设厅网站
  • 安阳网站公司哪家好兰州网站排名外包
  • 机械营销型网站泰安房产成交信息网
  • 网站源码下载教程网站建设中下载
  • 杭州网站建设宣盟网络网站怎么做导航条