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

知名的网站开发公司/微信小程序开发费用

知名的网站开发公司,微信小程序开发费用,php 爬取网站所有链接,上海外贸瓦屑包装袋有限公司1: Bean在Spring容器中是如何存储和定义的 Bean在Spring中的定义是_org.springframework.beans.factory.config.BeanDefinition_接口,BeanDefinition里面存储的就是我们编写的Java类在Spring中的元数据,包括了以下主要的元数据信息: 1&…

1: Bean在Spring容器中是如何存储和定义的

Bean在Spring中的定义是_org.springframework.beans.factory.config.BeanDefinition_接口,BeanDefinition里面存储的就是我们编写的Java类在Spring中的元数据,包括了以下主要的元数据信息:

1:Scope(Bean类型):包括了单例Bean(Singleton)和多实例Bean(Prototype)

2:BeanClass: Bean的Class类型

3:LazyInit:Bean是否需要延迟加载

4:AutowireMode:自动注入类型

5:DependsOn:Bean所依赖的其他Bean的名称,Spring会先初始化依赖的Bean

6:PropertyValues:Bean的成员变量属性值

7:InitMethodName:Bean的初始化方法名称

8:DestroyMethodName:Bean的销毁方法名称

同时BeanDefinition是存储到_org.springframework.beans.factory.support.DefaultListableBeanFactory类中维护的BeanDefinitionMap_中的,源码如下:

Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

了解了BeanDefinition的基础信息和存储位置后,接下来看看创建好的Bean实例是存储在什么地方的,创建好的Bean是存储在:_org.springframework.beans.factory.support.DefaultSingletonBeanRegistry_类中的

_singletonObjects_中的,Key是Bean的名称,Value就是创建好的Bean实例:

Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

了解了基本信息之后,就可以带着下面两个关键问题去分析Spring Bean的生命周期了:

1:Java类是如何被 Spring 扫描从而变成 BeanDefinition 的?

2:BeanDefinition是如何被 Spring 加工创建成我们可以直接使用的 Bean实例的?

2:Java类是如何被Spring扫描成为BeanDefinition的?

在Spring中定义Bean的方式有非常多,例如使用XML文件、注解,包括:@Component@Service@Configuration等,下面就以@Component注解为例来探究Spring是如何扫描我们的Bean的。我们知道使用@Component注解来标记Bean是需要配合@ComponentScan注解来使用的,而我们的主启动类上标注的@SpringBootApplication注解中就默认继承了@ComponentScan注解

@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication

所以最初的问题就转化成了**@ComponentScan**注解是如何在Spring中运作的

2.1 @ComponentScan注解是如何运作的

在Spring框架中,这个注解对应的处理类是_ComponentScanAnnotationParser,这个类的parse_方法是主要的处理逻辑,这个方法简要处理逻辑如下:

1:获取@ComponentScan注解中的basePackage属性,若没有则默认为该注解所标注类所在的包路径

2:使用ClassPathBeanDefinitionScannerscanCandidateComponents方法扫描classpath:+basePackage+/*.class**下的所有类资源文件

3:最后循环判断扫描的所有类资源文件,判断是否包含@Component注解,若有则将这些类注册到beandefinitionMap中

自此,我们代码里写的Java类,就被Spring扫描成BeanDefinition存储到了BeanDefinitionMap中了,扫描的细节大家可以去看看这个类的源码

3:Spring如何创建我们的Bean实例的

Spring把我们编写的Java类扫描成BeanDefinition之后,就会开始创建我们的Bean实例了,Spring将创建Bean的方法交给了_org.springframework.beans.factory.support.AbstractBeanFactory#getBean_方法,接下来就来看看getBean方法是如何创建Bean的

getBean方法的调用逻辑如下:getBean–> doGetBean --> createBean --> doCreateBean,最终Spring会使用org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean方法来创建Bean,创建Bean实例的主要逻辑分为了四个部分:创建Bean实例,填充Bean属性,初始化Bean,销毁Bean,接下来我们分别对这个四个部分进行探究

3.1 创建Bean实例

创建Bean实例的方法入口如下:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#__createBeanInstance

if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);
}

这个方法的主要逻辑是:推断出创建该Bean的构造器方法和参数,然后使用Java反射去创建Bean实例

3.2 填充Bean属性值populateBean方法

在这个方法中,主要是解析Bean需要注入的成员属性,然后将这些属性注入到该Bean中,如果该Bean有依赖的其他Bean则会优先去创建依赖的Bean,然后返回来继续创建该Bean,注意这里就会产生Bean创建的循环依赖问题,在本文的第6节中会详细说明

3.4:初始化Bean(initializeBean方法)

初始化Bean主要包括了四个部分:

3.4.1:invokeAwareMethods

在这个方法中主要调用实现的Aware接口中的方法,包括了BeanNameAware.setBeanName,BeanClassLoaderAware.setBeanClassLoader,BeanFactoryAware.setBeanFactory,这三个方法

Aware接口的功能:通过调用Aware接口中的set方法,将Spring容器中对应的Bean注入到正在创建的Bean中

3.4.2:调用前置处理方法:applyBeanPostProcessorsBeforeInitialization

在这个方法中主要是获取Spring容器中所有实现了_org.springframework.beans.factory.config.BeanPostProcessor接口的的实现类,然后循环调用postProcessBeforeInitialization_方法来加工正在创建的Bean

所以在这个方法中我们可以自定义_BeanPostProcessor_来扩展Bean的功能,实现自己的加工逻辑

3.4.3:调用Bean相关的初始化方法:

3.4.3.1 如果是InitializingBean则调用afterPropertiesSet方法

在这个流程中,Spring框架会判断正在创建的Bean是否实现了InitializingBean接口,如果实现了就会调用_afterPropertiesSet_方法来执行代码逻辑。

3.4.3.2 调用自定义初始化方法:initMethod

在这个流程中主要调用我们自定义的初始化方法,例如在xml文件中配置的_init-method和destory-method或者使用注解配置的@Bean(initMethod = “initMethod”, destroyMethod = “destroyMethod”)_ 方法

3.4.3.3:调用后置处理方法:applyBeanPostProcessorsAfterInitialization

在这个方法中主要是获取Spring容器中所有实现了_org.springframework.beans.factory.config.BeanPostProcessor接口的的实现类,然后循环调用postProcessAfterInitialization_来加工正在创建的Bean

在这个方法中我们可以自定义_BeanPostProcessor_来扩展Bean的功能,实现自己的加工逻辑

4:注册Bean销毁方法

在这里主要是注册Bean销毁时Spring回掉的方法例如:

1:xml文件中配置的destroy-method方法或者_@Bean注解中配置的destroyMethod_方法

2:_org.springframework.beans.factory.DisposableBean接口中的destory_方法

5:总结

到这里,从我们编写的Java类到Spring容器中可使用的Bean实例的创建过程就完整的梳理完成了,了解Bean的创建过程能够使我们更加熟悉Bean的使用方法,同时我们也可以在创建Bean的过程中新增自己的处理逻辑,从而实现将自己的组件接入Spring框架

6:Spring循环依赖的解决方法

Spring在创建Bean实例的时候,有时避免不了我们编写的Java类存在互相依赖的情况,如果Spring对这种互相依赖的情况不做处理,那么就会产生创建Bean实例的死循环问题,所以Spring对于这种情况必须特殊处理,下面就来探究Spring是如何巧妙处理Bean之间的循环依赖问题

6.1 暴露钩子方法getEarlyBeanReference

首先对于单实例类型的Bean来说,Spring在创建Bean的时候,会提前暴露一个钩子方法来获取这个正在创建中的Bean的地址引用,其代码如下:

如上面的代码所示,此时会在_singletonFactories这个Map中提前储存这个钩子方法singletonFactory_,从而能够提前对外暴露这个Bean的地址引用,那么为什么获取地址引用需要包装成复杂的方法呢?下面会解释

6.2 其他Bean获取提前暴露的Bean的地址引用

当其他Bean需要依赖正在创建中的Bean的时候,就会调用getSingleton方法来获取需要的Bean的地址引用

如上诉代码所示,在获取Bean的时候会从三个地方来获取

1:singletonObjects :这个是存放已经完全创建完成的Bean实例的Map

2:earlySingletonObjects :这个是存放用提前暴露的钩子方法创建好的Bean实例的Map

3:singletonFactories :这个是用来存放钩子方法的Map

当获取依赖的Bean的时候,就会调用钩子方法getEarlyBeanReference来获取提前暴露的Bean的引用,这个方法的源码如下:

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {Object exposedObject = bean;if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);}}}return exposedObject;
}

如上面的源码所示,这个方法主要是需要调用SmartInstantiationAwareBeanPostProcessorgetEarlyBeanReference方法来提前处理一下尚未创建完成的Bean,而getEarlyBeanReference方法有逻辑的实现类只有一个**org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator,**这个类就是创建Aop代理的类,其代码如下:

public Object getEarlyBeanReference(Object bean, String beanName) {Object cacheKey = this.getCacheKey(bean.getClass(), beanName);//提前标记这个bean已经创建过代理对象了this.earlyProxyReferences.put(cacheKey, bean);//按条件创建代理对象return this.wrapIfNecessary(bean, beanName, cacheKey);
}

如上面的代码所示,这段代码的主要目标就是判断提前暴露的Bean是否需要做动态代理,需要的话就会返回提前暴露的Bean的动态代理对象

那么这里为什么要去判断是否需要动态代理呢?考虑下面这种情况

1:如果这里不返回这个Bean的动态代理对象,但是这个Bean在后续的初始化流程中会存在动态代理:

举例:这里假设A依赖B,B又依赖A,此时B正在获取A提前暴露的引用,如果这时将A本身的地址引用返回给B,那么B里面就会保存A原始的地址引用,当B创建完成后,程序返回去创建A时,结果A在初始化的流程(initializingBean)中发生了动态代理,那么这时Spring容器中实际使用的是A的动态代理对象,而B却持有了原始A的引用,那么这时容器中就会存在A原始的引用以及A的动态代理的引用,从而产生歧义,这就是为什么需要提前去判断是否需要创建动态代理的原因,__这个原因的问题在于填充属性populateBean流程在初始化流程(initializingBean)之前,而创建动态代理的过程在初始化流程中

6.3 判断Bean的地址是否发生变化

Spring在Bean初始化之后,又判断了一下Bean初始化之后的地址是否发生了变化,其代码逻辑如下所示:

if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);//判断是否触发了提前创建bean的逻辑(getEarlyBeanReference)//如果有其他bean触发了提前创建bean的逻辑,那么这里就不为nullif (earlySingletonReference != null) {//判断引用地址是否发生了变化if (exposedObject == bean) {exposedObject = earlySingletonReference;}}
}

那么这里为什么需要在初始化之后继续判断Bean的地址是否发生了变化呢?

这是因为,如果存在循环依赖,同时Bean在初始化的流程(initializingBean)中又发生了额外的动态代理,例如,除了在**getEarlyBeanReference中发生的动态代理之外,还有额外的动态代理发生了,也就是发生了两次动态代理,那么这时Bean的地址与getEarlyBeanReference流程中产生的Bean的地址就不一样了,**这时如果不处理这种情况,又会出现Spring容器中同时存在两种不同的引用对象,又会造成歧义,所以Spring需要避免这种情况的存在

6.4 如果Bean地址发生变化则判断是否存在强依赖的Bean

Spring在Bean的创建过程中如果出现了上诉6.3节的情况时,Spring采取了下面的方法进行处理:

else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {//获取该Bean依赖的BeanString[] dependentBeans = getDependentBeans(beanName);Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);//去除因为类型检查而创建的Bean(doGetBean方法typeCheckOnly参数来控制)for (String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}//如果去除因为类型检查而创建的bean之外还存在依赖的bean//(这些剩下的bean就是spring实际需要使用的)那么就会抛出异常,阻止问题出现if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,"Bean with name '" + beanName + "' has been injected into other beans [" +StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +"] in its raw version as part of a circular reference, but has eventually been " +"wrapped. This means that said other beans do not use the final version of the " +"bean. This is often the result of over-eager type matching - consider using " +"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");}
}

上面这段代码就是Spring处理上诉情况的逻辑,首先明确的是Spring不允许上诉情况发生,Spring对于Bean的引用地址发生变化的情况,Spring首先会判断依赖的Bean是否已经完全创建完毕,如果存在完全创建完成的Bean就会直接抛出异常,因为这些完全创建完成的依赖Bean中持有的引用已经是旧地址引用了

具体的处理逻辑是:先拿到该Bean所有依赖的Bean,然后从这些Bean中排除仅仅是因为类型检查而创建的Bean,如果排除这些Bean之后,还有依赖的Bean,那么这些Bean就是可能存在循环依赖并且是强依赖的Bean(这些Bean中持有的引用地址是老地址,所以会存在问题),Spring就会及时抛出异常,避免发生问题

作者:京东物流 钟磊

来源:京东云开发者社区 自猿其说Tech 转载请注明来源

相关文章:

带着问题去分析:Spring Bean 生命周期 | 京东物流技术团队

1: Bean在Spring容器中是如何存储和定义的 Bean在Spring中的定义是_org.springframework.beans.factory.config.BeanDefinition_接口&#xff0c;BeanDefinition里面存储的就是我们编写的Java类在Spring中的元数据&#xff0c;包括了以下主要的元数据信息&#xff1a; 1&…...

C语言修行之函数篇(一)tolower —— 转换为小写字母

文章目录 函数说明函数声明函数返回值函数实现函数实例 函数说明 对于大写字母&#xff0c;如果在当前语言环境中存在小写表示形式&#xff0c;则tolower()返回其小写等效物。否则&#xff0c;tolower()函数执行相同的任务。 函数声明 #include <ctype.h> int tolower(…...

【JavaSE专栏55】Java集合类HashTable解析

&#x1f332;Java集合类HashTable解析 &#x1f332;Java集合类HashTable解析摘要引言Hashtable是什么&#xff1f;Hashtable vs. HashMap&#xff1a;何时使用Hashtable&#xff1f;多线程环境&#xff1a;历史遗留系统&#xff1a;不需要进行特殊操作&#xff1a; Hashtable…...

Apollo上机实践:一次对自动驾驶技术的亲身体验

上机实践 概述自动驾驶通信分布式系统开发模式开发工具 自动驾驶感知传感器特性感知流程及算法部署感知模型 自动驾驶决策规划决策规划流程和算法使用 Dreamview 进行控制在环的规划调试开发规划场景和算法 福利活动 主页传送门&#xff1a;&#x1f4c0; 传送 概述 Apollo 是…...

QTcpServer简单的TCP服务器连接

1、简介 简单实现控制TCP服务器获取连接的套接字。点击断开服务器即可关闭所有连接&#xff0c;最大连接数量为5个。 声明源文件 #include "mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent) {//设置固定大小setFixedSize(1024,600);b…...

LeetCode热题100——双指针

双指针 1.移动零2.盛最多水的容器3.三数之和 1.移动零 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 // 题解&#xff1a;使用双指针&#xff0c;其中快指针指向非零元素&#xff0c;慢指针指向首个零元素下…...

Ubuntu ARMv8编译Qt源码以及QtCreator

最近需要在NVIDIA小盒子上面跑一个程序&#xff0c;一开始想着在Ubuntu x64下交叉编译一版&#xff0c;后来发现libqxcb.so 这个库在configure时就会一直报错&#xff0c;多方查找怀疑可能是由于硬件不支持在x64环境下编译AMR架构的xcb库。 所以最后在ARM下直接编译Qt源码了&am…...

虚机Centos忘记密码如何重置

1进入开机前的页面&#xff0c;选中第一个&#xff0c;按“e”键&#xff0c;进入编辑模式 2找到ro crashkernel项&#xff0c;将ro替换成 rw initsysroot/bin/sh 3 Ctrlx mount -o remount, rw / chroot /sysroot chroot /sysroot passwd root 输入两次密码 touch /.a…...

OpenGL_Learn02

1. 监听窗口&#xff0c;绑定回调函数 #include <glad/glad.h> #include <GLFW/glfw3.h> #include <iostream>void framebuffer_size_callback(GLFWwindow* window, int width, int height) {glViewport(0, 0, width, height);std::cout << "变了…...

基于STC系列单片机实现外部中断0控制按键调节定时器0产生PWM(脉宽调制)的功能

#define uchar unsigned char//自定义无符号字符型为uchar #define uint unsigned int//自定义无符号整数型为uint sbit PwmOut P1^0;//位定义脉宽调制输出为单片机P1.0脚 uchar PwmTimeCount;//声明脉宽调制时间计数变量 uchar PwmDutyCycle;//声明脉宽调制占空比变量 void Ti…...

vue3中 reactive和ref的区别

在Vue 3中&#xff0c;reactive和ref都是用于响应式数据的API。它们的主要区别在于使用方式和返回值类型。 reactive&#xff1a; reactive函数用于将一个对象转换为响应式对象。它接收一个普通的JavaScript对象&#xff0c;并返回一个被代理的响应式对象。这意味着当响应式对…...

docker的安装部署nginx和mysql

小白自己整理&#xff0c;如有错误请指示&#xff01; 自我理解&#xff1a;docker就是把应用程序所用的依赖程序&#xff0c;函数库等相关文件打包成镜像文件&#xff0c;类似系统光盘&#xff0c;然后可以在任意电脑上安装使用&#xff08;方便运维人员部署程序&#xff09;…...

测试C#调用Aplayer播放视频(1:加载Aplayer控件)

微信公众号“Dotnet跨平台”的文章《开源精品&#xff0c;使用 C# 开发的 KTV 点歌项目》中使用了迅雷开源APlayer播放引擎。最近在学习有哪些能拿来播放视频的组件或控件&#xff0c;于是准备试试&#xff0c;根据文章中的介绍&#xff0c;在迅雷APlayer播放引擎网站中下载了A…...

二叉树的遍历+二叉树的基本操作

文章目录 二叉树的操作一、 二叉树的存储1.二叉树的存储结构 二、 二叉树的基本操作1.前置创建一棵二叉树&#xff1a;1. 定义结点 2.简单的创建二叉树 2.二叉数的遍历1.前序遍历2.中序遍历3.后序遍历4.层序遍历 3.二叉树的操作1.获取树中节点的个数2.获取叶子节点的个数3.获取…...

Go 语言gin框架的web

节省时间与精力&#xff0c;更高效地打造稳定可靠的Web项目&#xff1a;基于Go语言和Gin框架的完善Web项目骨架。无需从零开始&#xff0c;直接利用这个骨架&#xff0c;快速搭建一个功能齐全、性能优异的Web应用。充分发挥Go语言和Gin框架的优势&#xff0c;轻松处理高并发、大…...

Docker底层原理:Cgroup V2的使用

文章目录 检查 cgroup2 文件系统是否已加载检查系统是否已挂载 cgroup2 文件系统创建 cgroup2 层次结构查看 cgroup2 开启的资源控制类型启用 cgroup2 资源控制设置 cgroup2 资源限制加入进程到 cgroup2 检查 cgroup2 文件系统是否已加载 cat /proc/filesystems | grep cgroup…...

历年上午真题笔记(2014年)

解析:A 网络设计的三层模型 : 接入层:Layer 2 Switching,最终用户被许可接入网络的点,用户通过接入层可以访问网络设备。 汇聚层:Layer2/3 Switching,访问层设备的汇聚点,负责汇接配线单元,利用二、三层技术实现工作组分段及网络故障的隔离,以免对核心层网络设备造…...

数据库软考知识

分布式数据库透明性 封锁 加上共享锁之后只能加共享锁&#xff0c;加上排他锁之后&#xff0c;啥锁都不能加。 分布式数据库特性 伪传递定理 SQL函数定义&#xff0c;有点冷 来了奥&#xff0c;更冷 存储过程 很重要&#xff0c;下午第二大题也是数据库...

学习笔记|配对样本均数T检验|SPSS常用的快捷键|规范表达|《小白爱上SPSS》课程:SPSS第六讲 | 配对样本均数T检验

目录 学习目的软件版本原始文档配对样本均数T检验一、实战案例二、案例解析三、统计策略四、SPSS操作1、正态性检验2、配对样本T检验 五、结果解读六、规范报告1、规范表格2、规范文字 划重点Tips:SPSS常用的快捷键 学习目的 SPSS第六讲 | 配对样本均数T检验 软件版本 IBM S…...

python内置模块smtplib、email 发送电子邮件

一、简介 smtplib 是 Python 的标准库之一&#xff0c;用于发送电子邮件。它提供了一个简单的接口来连接到 SMTP&#xff08;Simple Mail Transfer Protocol&#xff09;服务器&#xff0c;并通过该服务器发送电子邮件。 email 是 Python 的标准库之一&#xff0c;用于处理电子…...

Qt使用QWebEngineView一些记录

1.关闭软件警告&#xff1a; Release of profile requested but WebEnginePage still not deleted. Expect troubles! 原因&#xff0c;系统退出关闭view&#xff0c;没有释放page。 解决办法&#xff1a;手动释放page 顺便把view也释放了。 Widget::~Widget() {updateIni…...

【2023.10.30练习】C语言-判断等式成立

计算机能力挑战初赛2020.20题 题目描述&#xff1a; 输入正整数A、B、C(0<A,B,C<10000),若用、-、*、/、%之一组成等式(即ABC&#xff0c;是上述运算符之一&#xff0c;)&#xff0c;则输出“YES”&#xff0c;否则输出“NO”&#xff1b; 输入&#xff1a; 第一行输入…...

Wpf 使用 Prism 实战开发Day03

一.实现左侧菜单绑定 效果图: 1.首先需要在项目中创建 mvvm 的架构模式 创建 Models &#xff0c;放置实体类。 实体类需要继承自Prism 框架的 BindableBase&#xff0c;目的是让实体类支持数据的动态变更! 例如: 系统导航菜单实体类 / <summary>/// 系统导航菜单实体类…...

JavaEE-cookie和session

本部分内容包括 cookie基本概念&#xff0c;sendcookies和getcookies代码&#xff1b; session基本概念&#xff0c;session实现登陆界面&#xff1b; 上述过程中涉及的代码如下&#xff1a; 1 import javax.servlet.ServletException; import javax.servlet.annotation.WebSe…...

Java设计模式之命令模式

目录 定义 结构 案例 优点 缺点 使用场景 JDK源码解析 Thread中start与run方法的区别 定义 将一个请求封装为一个对象&#xff0c;使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通&#xff0c;这样方便将命令对象进行存储、传递、调用、增…...

记录一段帮朋友写的代码,使用牛顿-拉夫逊方法解方程

要求 已知公式&#xff1a; t G A B F r B r 2 2 F A 2 B G A F ln ⁡ ( r − A ) C o n s t t\frac{GAB}{F}r\frac{Br^2}{2F}\frac{A^2BGA}{F}\ln (r-A)Const tFGAB​r2FBr2​FA2BGA​ln(r−A)Const 其中 t 的值为0-1000&#xff0c;每间隔25取一次值A2.12941E-10B0.…...

滑动窗口限流算法实现一

固定算法 原理&#xff1a;固定算法是将时间线分隔成固定大小的时间窗口&#xff0c;每个窗口都会有个计数器&#xff0c;用来记录窗口时间范围内的请求总数&#xff0c;如果窗口的请求总数达到最大限定值&#xff0c;会认定流量超限。比如将窗口大小设为1分钟&#xff0c;每分…...

简单明了!网关Gateway路由配置filters实现路径重写及对应正则表达式的解析

问题背景&#xff1a; 前端需要发送一个这样的请求&#xff0c;但出现404 首先解析请求的变化&#xff1a; http://www.51xuecheng.cn/api/checkcode/pic 1.请求先打在nginx&#xff0c;www.51xuecheng.cn/api/checkcode/pic部分匹配到了之后会转发给网关进行处理变成localho…...

EMQX内置Web管理控制台-Dashboard

一、Dashboard概述 EMQX Dashboard官网文档&#xff1a;https://docs.emqx.com/zh/enterprise/v5.1/dashboard/introduction.html 1、简介 EMQX 为用户提供了一个功能强大的内置管理控制台&#xff0c;即 EMQX Dashboard。通过这个控制台的 Web 界面&#xff0c;用户可以轻松监…...

计算机网络重点概念整理-第四章 网络层【期末复习|考研复习】

计算机网络复习系列文章传送门&#xff1a; 第一章 计算机网络概述 第二章 物理层 第三章 数据链路层 第四章 网络层 第五章 传输层 第六章 应用层 第七章 网络安全 计算机网络整理-简称&缩写 文章目录 前言四、网络层4.1 网络层功能4.1.1 电路交换、报文交换与分组交换4.1…...