SpringBoot源码阅读(10)——后处理器
后处理器是在监听器EnvironmentPostProcessorApplicationListener
中被加载。
入口在SpringApplication
实例方法prepareEnvironment
,第343行。
listeners.environmentPrepared(bootstrapContext, environment);
这里触发了事件ApplicationEnvironmentPreparedEvent
相关监听器
监听器 | Order |
---|---|
DelegatingApplicationListener | 0 |
EnvironmentPostProcessorApplicationListener | Integer.MIN_VALUE + 10 |
LoggingApplicationListener | Integer.MIN_VALUE + 20 |
AnsiOutputApplicationListener | Integer.MIN_VALUE + 11 |
FileEncodingApplicationListener | Integer.MAX_VALUE |
排序后,触发顺序
DelegatingApplicationListener
EnvironmentPostProcessorApplicationListener
AnsiOutputApplicationListener
LoggingApplicationListener
FileEncodingApplicationListener
EnvironmentPostProcessorApplicationListener
就是监听器之一。
EnvironmentPostProcessorApplicationListener
主要方法
private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {ConfigurableEnvironment environment = event.getEnvironment();SpringApplication application = event.getSpringApplication();for (EnvironmentPostProcessor postProcessor : getEnvironmentPostProcessors(application.getResourceLoader(),event.getBootstrapContext())) {postProcessor.postProcessEnvironment(environment, application);}
}
List<EnvironmentPostProcessor> getEnvironmentPostProcessors(ResourceLoader resourceLoader,ConfigurableBootstrapContext bootstrapContext) {ClassLoader classLoader = (resourceLoader != null) ? resourceLoader.getClassLoader() : null;EnvironmentPostProcessorsFactory postProcessorsFactory = this.postProcessorsFactory.apply(classLoader);return postProcessorsFactory.getEnvironmentPostProcessors(this.deferredLogs, bootstrapContext);
}
其中this.postProcessorsFactory
是EnvironmentPostProcessorsFactory::fromSpringFactories
static EnvironmentPostProcessorsFactory fromSpringFactories(ClassLoader classLoader) {return new ReflectionEnvironmentPostProcessorsFactory(classLoader,SpringFactoriesLoader.loadFactoryNames(EnvironmentPostProcessor.class, classLoader));
}
EnvironmentPostProcessor
的实现类
# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor,\
org.springframework.boot.env.RandomValuePropertySourceEnvironmentPostProcessor,\
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor,\
org.springframework.boot.reactor.DebugAgentEnvironmentPostProcessor# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.autoconfigure.integration.IntegrationPropertiesEnvironmentPostProcessor
处理器 | Order值 |
---|---|
CloudFoundryVcapEnvironmentPostProcessor | Integer.MIN_VALUE + 10 - 1 |
ConfigDataEnvironmentPostProcessor | Integer.MIN_VALUE + 10 |
RandomValuePropertySourceEnvironmentPostProcessor | Integer.MIN_VALUE + 1 |
SpringApplicationJsonEnvironmentPostProcessor | Integer.MIN_VALUE + 5 |
SystemEnvironmentPropertySourceEnvironmentPostProcessor | Integer.MIN_VALUE + 5 - 1 |
DebugAgentEnvironmentPostProcessor | Integer.MAX_VALUE |
IntegrationPropertiesEnvironmentPostProcessor | Integer.MAX_VALUE |
最后顺序
RandomValuePropertySourceEnvironmentPostProcessor
SystemEnvironmentPropertySourceEnvironmentPostProcessor
SpringApplicationJsonEnvironmentPostProcessor
CloudFoundryVcapEnvironmentPostProcessor
ConfigDataEnvironmentPostProcessor
DebugAgentEnvironmentPostProcessor
IntegrationPropertiesEnvironmentPostProcessor
EnvironmentPostProcessorApplicationListener
实例化的时候,是调用的无参构造方法。
public EnvironmentPostProcessorApplicationListener() {this(EnvironmentPostProcessorsFactory::fromSpringFactories, new DeferredLogs());
}
实例化后关键属性
属性 | 值 |
---|---|
postProcessorsFactory | EnvironmentPostProcessorsFactory::fromSpringFactories |
deferredLogs | DeferredLogFactory |
ReflectionEnvironmentPostProcessorsFactory
实例化后的属性
属性 | 值 |
---|---|
classes | null |
classLoader | null |
classNames | EnvironmentPostProcessor实现类的类全限定名\ |
加载EnvironmentPostProcessor
实现类的主要逻辑
@Override
public List<EnvironmentPostProcessor> getEnvironmentPostProcessors(DeferredLogFactory logFactory,ConfigurableBootstrapContext bootstrapContext) {Instantiator<EnvironmentPostProcessor> instantiator = new Instantiator<>(EnvironmentPostProcessor.class,(parameters) -> {parameters.add(DeferredLogFactory.class, logFactory);parameters.add(Log.class, logFactory::getLog);parameters.add(ConfigurableBootstrapContext.class, bootstrapContext);parameters.add(BootstrapContext.class, bootstrapContext);parameters.add(BootstrapRegistry.class, bootstrapContext);});return (this.classes != null) ? instantiator.instantiateTypes(this.classes): instantiator.instantiate(this.classLoader, this.classNames);
}
public Instantiator(Class<?> type, Consumer<AvailableParameters> availableParameters) {this(type, availableParameters, throwingFailureHandler);
}
public Instantiator(Class<?> type, Consumer<AvailableParameters> availableParameters,FailureHandler failureHandler) {this.type = type;this.availableParameters = getAvailableParameters(availableParameters);this.failureHandler = failureHandler;
}
Instantiator
是一个通过用的实例化工具类。
主要逻辑:
- 获取要实例化的类的构造方法,按照构造方法的参数个数倒序排序。
- 然后检查每个参数,是否是给定参数集合中类的子类或者类本身。
- 如果找到了,就把给定参数集合中的值作为参数返回,拿去调用构造方法
- 优先使用个数多个的构造方法,默认使用无参构造
- 构造完成后,使用
AnnotationAwareOrderComparator
比较器排序一番。
属性 | 值 |
---|---|
type | EnvironmentPostProcessor.class |
availableParameters | DeferredLogFactory.class factoryType -> DeferredLogs |
Log.class | logFactory::getLog |
ConfigurableBootstrapContext.class | factoryType -> bootstrapContext |
BootstrapContext.class | factoryType -> bootstrapContext |
BootstrapRegistry.class | factoryType -> bootstrapContext |
failureHandler | 初始化失败后的处理器,默认是抛异常 |
RandomValuePropertySourceEnvironmentPostProcessor
构造方法
public RandomValuePropertySourceEnvironmentPostProcessor(Log logger) {this.logger = logger;
}
SystemEnvironmentPropertySourceEnvironmentPostProcessor
默认无参构造
SpringApplicationJsonEnvironmentPostProcessor
默认无参构造
CloudFoundryVcapEnvironmentPostProcessor
构造方法
public CloudFoundryVcapEnvironmentPostProcessor(Log logger) {this.logger = logger;
}
ConfigDataEnvironmentPostProcessor
构造方法
public ConfigDataEnvironmentPostProcessor(DeferredLogFactory logFactory,ConfigurableBootstrapContext bootstrapContext) {this(logFactory, bootstrapContext, null);
}public ConfigDataEnvironmentPostProcessor(DeferredLogFactory logFactory,ConfigurableBootstrapContext bootstrapContext,ConfigDataEnvironmentUpdateListener environmentUpdateListener) {this.logFactory = logFactory;this.logger = logFactory.getLog(getClass());this.bootstrapContext = bootstrapContext;this.environmentUpdateListener = environmentUpdateListener;
}
DebugAgentEnvironmentPostProcessor
默认无参构造
IntegrationPropertiesEnvironmentPostProcessor
默认无参构造
最后得到各自的构造方法
类 | 构造方法 |
---|---|
RandomValuePropertySourceEnvironmentPostProcessor | public RandomValuePropertySourceEnvironmentPostProcessor(Log logger) |
SystemEnvironmentPropertySourceEnvironmentPostProcessor | 无参构造 |
SpringApplicationJsonEnvironmentPostProcessor | 无参构造 |
CloudFoundryVcapEnvironmentPostProcessor | public CloudFoundryVcapEnvironmentPostProcessor(Log logger) |
ConfigDataEnvironmentPostProcessor | public ConfigDataEnvironmentPostProcessor(DeferredLogFactory logFactoryConfigurableBootstrapContext bootstrapContext) |
DebugAgentEnvironmentPostProcessor | 无参构造 |
IntegrationPropertiesEnvironmentPostProcessor | 无参构造 |
实例化后排序 |
RandomValuePropertySourceEnvironmentPostProcessor
SystemEnvironmentPropertySourceEnvironmentPostProcessor
SpringApplicationJsonEnvironmentPostProcessor
CloudFoundryVcapEnvironmentPostProcessor
ConfigDataEnvironmentPostProcessor
DebugAgentEnvironmentPostProcessor
IntegrationPropertiesEnvironmentPostProcessor
逻辑
RandomValuePropertySourceEnvironmentPostProcessor
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {RandomValuePropertySource.addToEnvironment(environment, this.logger);
}
这个处理器会创建一个Random
对象,放入sources
,key
为random
如果环境变量已经加载,就放在环境变量后面,没有加载,就放到最后
SystemEnvironmentPropertySourceEnvironmentPostProcessor
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {String sourceName = StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME;PropertySource<?> propertySource = environment.getPropertySources().get(sourceName);if (propertySource != null) {replacePropertySource(environment, sourceName, propertySource, application.getEnvironmentPrefix());}
}@SuppressWarnings("unchecked")
private void replacePropertySource(ConfigurableEnvironment environment, String sourceName,PropertySource<?> propertySource, String environmentPrefix) {Map<String, Object> originalSource = (Map<String, Object>) propertySource.getSource();SystemEnvironmentPropertySource source = new OriginAwareSystemEnvironmentPropertySource(sourceName,originalSource, environmentPrefix);environment.getPropertySources().replace(sourceName, source);
}
这个处理器会处理系统环境变量,把系统环境变量包装成OriginAwareSystemEnvironmentPropertySource
SpringApplicationJsonEnvironmentPostProcessor
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {MutablePropertySources propertySources = environment.getPropertySources();propertySources.stream().map(JsonPropertyValue::get).filter(Objects::nonNull).findFirst().ifPresent((v) -> processJson(environment, v));
}
private void processJson(ConfigurableEnvironment environment, JsonPropertyValue propertyValue) {JsonParser parser = JsonParserFactory.getJsonParser();Map<String, Object> map = parser.parseMap(propertyValue.getJson());if (!map.isEmpty()) {addJsonPropertySource(environment, new JsonPropertySource(propertyValue, flatten(map)));}
}
public static JsonParser getJsonParser() {if (ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", null)) {return new JacksonJsonParser();}if (ClassUtils.isPresent("com.google.gson.Gson", null)) {return new GsonJsonParser();}if (ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", null)) {return new YamlJsonParser();}return new BasicJsonParser();
}
这个处理器会从环境变量中获取spring.application.json
或者SPRING_APPLICATION_JSON
的配置,然后找到第一个配置,使用json解析器解析,放入source
,名称为spring.application.json
,位置在servletContextInitParams
或者servletConfigInitParams
之前。
CloudFoundryVcapEnvironmentPostProcessor
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {if (CloudPlatform.CLOUD_FOUNDRY.isActive(environment)) {Properties properties = new Properties();JsonParser jsonParser = JsonParserFactory.getJsonParser();addWithPrefix(properties, getPropertiesFromApplication(environment, jsonParser), "vcap.application.");addWithPrefix(properties, getPropertiesFromServices(environment, jsonParser), "vcap.services.");MutablePropertySources propertySources = environment.getPropertySources();if (propertySources.contains(CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME)) {propertySources.addAfter(CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME,new PropertiesPropertySource("vcap", properties));}else {propertySources.addFirst(new PropertiesPropertySource("vcap", properties));}}
}
这个处理器,会从环境变量获取spring.main.cloud-platform
的值,如果是CloudPlatform.CLOUD_FOUNDRY
类型,如果值是CLOUD_FOUNDRY
或者包含VCAP_APPLICATION
或VCAP_SERVICES
,就执行开源云平台的逻辑。
从环境变量中获取VCAP_APPLICATION
和VCAP_SERVICES
的值,用json解析器解析,分别加上前缀vcap.application.
和vcap.services.
,放入sources
,名称是vcap
,位置上,如果有命令行参数,就放在命令行参数后面,如果没有,就放首位。
ConfigDataEnvironmentPostProcessor
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {postProcessEnvironment(environment, application.getResourceLoader(), application.getAdditionalProfiles());
}
ConfigDataEnvironment getConfigDataEnvironment(ConfigurableEnvironment environment, ResourceLoader resourceLoader,Collection<String> additionalProfiles) {return new ConfigDataEnvironment(this.logFactory, this.bootstrapContext, environment, resourceLoader,additionalProfiles, this.environmentUpdateListener);
}
创建一个ConfigDataEnvironment
实例,过程中会创建一个ConfigDataLocationResolvers
实例。
ConfigDataEnvironment(DeferredLogFactory logFactory, ConfigurableBootstrapContext bootstrapContext,ConfigurableEnvironment environment, ResourceLoader resourceLoader, Collection<String> additionalProfiles,ConfigDataEnvironmentUpdateListener environmentUpdateListener) {Binder binder = Binder.get(environment);UseLegacyConfigProcessingException.throwIfRequested(binder);this.logFactory = logFactory;this.logger = logFactory.getLog(getClass());this.notFoundAction = binder.bind(ON_NOT_FOUND_PROPERTY, ConfigDataNotFoundAction.class).orElse(ConfigDataNotFoundAction.FAIL);this.bootstrapContext = bootstrapContext;this.environment = environment;this.resolvers = createConfigDataLocationResolvers(logFactory, bootstrapContext, binder, resourceLoader);this.additionalProfiles = additionalProfiles;this.environmentUpdateListener = (environmentUpdateListener != null) ? environmentUpdateListener: ConfigDataEnvironmentUpdateListener.NONE;this.loaders = new ConfigDataLoaders(logFactory, bootstrapContext, resourceLoader.getClassLoader());this.contributors = createContributors(binder);
}
感觉像是捅了马蜂窝了。
ConfigDataLocationResolvers
实例化,会加载ConfigDataLocationResolver
的实现类。
# ConfigData Location Resolvers
org.springframework.boot.context.config.ConfigDataLocationResolver=\
org.springframework.boot.context.config.ConfigTreeConfigDataLocationResolver,\
org.springframework.boot.context.config.StandardConfigDataLocationResolver
ConfigTreeConfigDataLocationResolver
实例化,会创建LocationResourceLoader
实例
StandardConfigDataLocationResolver
实例化,会加载PropertySourceLoader
的实现类
# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader
StandardConfigDataLocationResolver
中会设置应用的配置文件名称,key是spring.config.name
,默认值是application
,也就是Spring
配置文件的名字也是可以配置的,这个名字中不能包含*号。
至于PropertiesPropertySourceLoader
和YamlPropertySourceLoader
,就是解析Spring
配置文件的两个加载器,前者解析properties
后缀文件,后者解析yml
后缀文件。
ConfigDataLocationResolvers
中,在加载完成ConfigDataLocationResolver
的接口后,会重新排序,把StandardConfigDataLocationResolver
的子类或本身保留最后实现,放入集合末尾。
ConfigDataEnvironment
实例化时,会创建ConfigDataLoaders
实例,进而加载ConfigDataLoader
的实例。
# ConfigData Loaders
org.springframework.boot.context.config.ConfigDataLoader=\
org.springframework.boot.context.config.ConfigTreeConfigDataLoader,\
org.springframework.boot.context.config.StandardConfigDataLoader
然后调用processAndApply
,会读取配置文件。
void processAndApply() {ConfigDataImporter importer = new ConfigDataImporter(this.logFactory, this.notFoundAction, this.resolvers,this.loaders);registerBootstrapBinder(this.contributors, null, DENY_INACTIVE_BINDING);ConfigDataEnvironmentContributors contributors = processInitial(this.contributors, importer);ConfigDataActivationContext activationContext = createActivationContext(contributors.getBinder(null, BinderOption.FAIL_ON_BIND_TO_INACTIVE_SOURCE));contributors = processWithoutProfiles(contributors, importer, activationContext);activationContext = withProfiles(contributors, activationContext);contributors = processWithProfiles(contributors, importer, activationContext);applyToEnvironment(contributors, activationContext, importer.getLoadedLocations(),importer.getOptionalLocations());
}private ConfigDataEnvironmentContributors processInitial(ConfigDataEnvironmentContributors contributors,ConfigDataImporter importer) {this.logger.trace("Processing initial config data environment contributors without activation context");contributors = contributors.withProcessedImports(importer, null);registerBootstrapBinder(contributors, null, DENY_INACTIVE_BINDING);return contributors;
}
相关文章:

SpringBoot源码阅读(10)——后处理器
后处理器是在监听器EnvironmentPostProcessorApplicationListener中被加载。 入口在SpringApplication实例方法prepareEnvironment,第343行。 listeners.environmentPrepared(bootstrapContext, environment);这里触发了事件ApplicationEnvironmentPreparedEvent 相…...

【源码开源】C#桌面应用开发:串口调试助手
c#桌面应用开发 1、环境搭建和工程创建:参照番茄定时器项目 工程创建参照 2、界面布局设计 3、具体功能函数 (1)端口扫描: private void btn_com_scan_Click(object sender, EventArgs e){//端口号扫描ReflashPortToComboBox(…...

malloc与free函数的用法(精简全面 · 一看即懂)
前言:Hello大家好😘,我是心跳sy,今天为大家带来malloc函数与free函数的用法,我们一起来看看吧! 目录 一、malloc函数 💫 1、⭐️malloc函数对应的头文件⭐️ 2、⭐️malloc函数的作用⭐️ 3…...

强制升级最新系统,微软全面淘汰Win10和部分11用户
说出来可能不信,距离 Windows 11 正式发布已过去整整三年时间,按理说现在怎么也得人均 Win 11 水平了吧? 然而事实却是,三年时间过去 Win 11 占有率仅仅突破到 29%,也就跳起来摸 Win 10 屁股的程度。 2024 年 6 月 Wi…...

java-命令行连接 mysql
在 Java 中,通过命令行连接 MySQL 可以使用以下步骤。假设您已经安装并配置了 MySQL 5.7。 ### 一、通过命令行连接 MySQL #### 1. 打开命令行终端 在不同的操作系统上打开命令行终端的方式: - **Windows**:按 Win R 键,输入…...

RK3588部署YOLOV8-seg的问题
在使用YOLOV8-seg训练出来的pt模型转为onnx的时候,利用以下仓库地址转。 git clone https://github.com/airockchip/ultralytics_yolov8.git 在修改ultralytics/cfg/default.yaml中的task,mode为model为自己需要的内容后, 执行以下语句 cd …...

Python Linux下编译
注意 本教程针对较新Linux系统,没有升级依赖、处理旧版本Linux的openssl等步骤,如有需要可以查看往期文章,例如:在Centos7.6镜像中安装Python3.9 教程中没有使用默认位置、默认可执行文件名,请注意甄别 安装路径&#…...

SpringMVC(3)——SpringMVC注解实战
前言 SpringMVC(2)——controller方法参数与html表单对应(请求参数的绑定) 上篇博客我们提到了controller方法的参数与html表单之间的对应关系 但是这种对应关系有很多缺点: 传递参数只能放在request的body当中&am…...

统信UOS上批量安装惠普打印驱动后启动器没有图标的解决方法
原文链接:统信UOS上批量安装惠普打印驱动后启动器没有图标的解决方法 Hello,大家好啊!今天给大家带来一篇关于在统信UOS上批量安装惠普打印驱动后启动器没有设置图标的解决方法的文章。批量安装打印驱动是企业和个人用户常见的操作࿰…...

Python UDP编程之实时聊天与网络监控详解
概要 UDP(User Datagram Protocol,用户数据报协议)是网络协议中的一种,主要用于快速、简单的通信场景。与TCP相比,UDP没有连接、确认、重传等机制,因此传输效率高,但也不保证数据的可靠性和顺序。本文将详细介绍Python中如何使用UDP协议进行网络通信,并包含相应的示例…...

LiveNVR监控流媒体Onvif/RTSP用户手册-用户管理:编辑、添加用户、关联通道、重置密码、删除、过滤搜索
LiveNVR监控流媒体Onvif/RTSP用户手册-用户管理:编辑、添加用户、关联通道、重置密码、删除、过滤搜索 1、用户管理1.1、添加用户1.2、关联通道1.3、重置密码1.4、编辑1.5、删除1.6、过滤搜索 2、RTSP/HLS/FLV/RTMP拉流Onvif流媒体服务 1、用户管理 1.1、添加用户 点击用户管理…...

SpringBoot新手快速入门系列教程十:基于Docker Compose,部署一个简单的项目
前述: 本篇教程将略过很多docker下载环境配置的基础步骤,如果您对docker不太熟悉请参考我的上一个教程:SpringBoot新手快速入门系列教程九:基于docker容器,部署一个简单的项目 使用 Docker Compose 支持部署 Docker 项…...

websocket中的STOMP 协议:sockjs-client 和 stompjs
文章目录 一、简介二、安装三、创建 webSocket.ts四、页面中使用一、简介 使用 WebSockets 进行实时通信时,一种常见的实现方式是使用 STOMP 协议。STOMP(Simple Text Oriented Messaging Protocol)是一种轻量级的协议,通常用于客户端和消息代理之间的通信,如 WebSockets…...

阿里云API安全2.0全新发布
阿里云安全发布API防护产品已将近三年,为客户提供API资产全生命周期监控管理,发现和管理业务中存在的全量API接口资产,并提升API接口在数据流转过程中的安全性,现已全面覆盖OWASP提出的API TOP 10安全风险。 近期,阿里…...

学习网络的第一步:全面解析OSI与TCP/IP模型
我是小米,一个喜欢分享技术的29岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货! Hello,大家好!我是你们的好朋友小米。今天我们来聊一聊网络基础知识中的重量级选手——OSI模型和TCP/IP模型!网络的世界就像一个巨大的迷宫,而这两个…...

鸿蒙语言基础类库:【@ohos.util (util工具函数)】
util工具函数 说明: 本模块首批接口从API version 7开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。开发前请熟悉鸿蒙开发指导文档:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 该模块…...

CVPR`24 | 又快又好!渲染速度比ENeRF快30倍!4K4D:实时4K分辨率4D视图合成
文章链接:https://arxiv.org/pdf/2310.11448 git链接: https://zju3dv.github.io/4k4d/ 本文旨在实现动态3D场景在4K分辨率下的高保真和实时视图合成。最近,一些动态视图合成方法在渲染质量方面表现出色。然而,在渲染高分辨率图像…...

中关村软件园发布“数据合规与出境评估服务平台”
在2024中关村论坛年会期间,中关村软件园发布“数据合规与出境评估服务平台”。该平台是中关村软件园结合北京市“两区”建设,立足软件园国家数字服务出口基地和数字贸易港建设,围绕园区内外部企业用户的业务合作、科研创新、跨国运营等场景需…...

记一次若依框架和Springboot常见报错的实战漏洞挖掘
目录 前言 本次测实战利用图 1.判段系统框架 2.登录页面功能点测试 2.1 弱口令 2.2 webpack泄露信息判断 2.3 未授权接口信息发现 3.进一步测试发现新的若依测试点 3.1 默认弱口令 3.2 历史漏洞 4.访问8080端口发现spring经典爆粗 4.1 druid弱口令 4.2 SwaggerU…...

Idea合并Git分支信息
#git 的笔记 ##本篇文章是通过Idea 实现git 命令操作的代码的上传与合并。 1.合并分支 点击 Git 选择Merge 这里选择合并远程的分支...

【学习css2】grid布局-页面footer部分保持在网页底部
中间内容高度不够屏幕高度撑不开的页面时候,页面footer部分都能保持在网页页脚(最底部)的方法 1、首先上图看显示效果 2、奉上源码 2.1、html部分 <body><header>头部</header><main>主区域</main><foot…...

Django 表单
Django 表单 Django 表单是 Web 开发中不可或缺的一部分,它允许用户与网站进行交互,如提交数据、上传文件等。在 Django 框架中,表单功能非常强大,支持各种自定义和验证,使得开发者能够轻松地处理用户输入。本文将详细介绍 Django 表单的使用方法,包括创建表单、表单字段…...

【Linux网络】网络基础
本篇博客整理了 Linux 网络编程的前置知识,例如网络的发展、协议和协议栈分层、网络通信原理、网络地址等,为后续进入 Linux 网络编程作铺垫。 目录 一、网络发展 二、网络协议 1)协议的作用 2)协议栈 3)协议分层…...

Open3D 可视化点云配准中匹配点之间的连线
目录 一、概述 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 3.1原始点云 3.2处理后的点云 一、概述 在点云配准的过程中,可视化匹配点之间的连线(匹配线)有助于更直观地理解配准结果和误差分布。以下是可视化匹配点之间连线的好处和作用: 1. 直观理…...

Linux编程第三篇:Linux简介,开源软件简介(Linux是否安全?参考TESEC指标)
业精于勤荒于嬉,行成于思毁于随。 今天这篇算是Linux的正式学习,废话不多说,我们开始吧 第三篇 一、UNIX与Linux发展史1.1、UNIX发展历史和发行版本1.2、UNIX主要发行版本1.3、Linux发展历史1.4、Linux内核版本1.5、Linux主要发行版本 二、开…...

【JavaSE复习】数据结构、集合
JavaSE 复习 1.数据结构1.1 查找1.1.1 基本查找1.1.2 二分查找1.1.3 插值查找1.1.4 斐波那契查找1.1.5 分块查找1.1.6 分块查找的扩展(无规律数据) 1.2 排序1.2.1 冒泡排序1.2.2 选择排序1.2.3 插入排序1.2.4 快速排序 2. 集合2.1 基础集合2.1.1 集合和数…...

Java版Flink使用指南——自定义无界流生成器
大纲 新建工程自定义无界流 使用打包、提交、运行工程代码 在《Java版Flink使用指南——从RabbitMQ中队列中接入消息流》一文中,我们让外部组件RabbitMQ充当了无界流的数据源,使得Flink进行了流式处理。在《Java版Flink使用指南——将消息写入到RabbitMQ…...

Vue3框架搭建4:配置说明-eslint配置
配置说明: .eslintrc.cjs: /* eslint-env node */ //node环境,并引入一个模块解析补丁 require(rushstack/eslint-patch/modern-module-resolution)module.exports { //继承其他配置root: true, //跟配置文件,ESLint不会在父目…...

JavaFx+MySql学生管理系统
前言: 上个月学习了javafx和mysql数据库,于是写了一个学生管理系统,因为上个月在复习并且有一些事情,比较忙,所以没有更新博客了,这个项目页面虽然看着有点简陋了,但是大致内容还是比较简单的,于是现在跟大家分享一下我的学生管理系统,希望对这方面有兴趣的同学提供一些帮助 &a…...

Java--抽象类
1.抽象--abstract 2.不能对抽象类进行实例化,也就是不能new这个抽象类 3.抽象类的应用,就是在class前加入abstract这个单词,同理抽象方法也是在void前加入abstract 4.在抽象类中可以写普通方法,但抽象方法只能写在抽象类中 5.…...