网站充值如何做post的/crm
系列文章目录
前言
本节我们的Dubbo源码版本基于2.6.x
在前一章我们的整合案例中,我们有几个比较关键的步骤:
- 在启动类上标注了
@EnableDubbo
注解 - 在provider类上面标注了
@Service
注解来提供dubbo服务 - 在消费的时候通过
@Reference
注解引入dubbo服务 - 在配置文件中配置应用名,协议,暴露端口,注册中心地址等。
- 在配置文件中配置应用名,协议,暴露端口,注册中心地址等。
一、EnableDubbo注解
- 这里可以看到
EnableDubbo
是一个复合注解,集成了@EnableDubboConfig
和@DubboComponentScan
注解
2.EnableDubbo
注解的属性,其中scanBasePackages
和scanBasePackageClasses
默认都是空,这里是可以指定包扫描的路径或者基类的,然后multipleConfig
默认是true
。
1.1、EnableDubboConfig注解
- 这里使用
import
注解导入了DubboConfigConfigurationRegistrar
- 这里
EnableDubboConfig
注解中的multiple
属性默认为true
1.1.1、DubboConfigConfigurationRegistrar
- 首先获取
EnableDubboConfig
注解中的属性列表- 这里会根据注解中的
multiple
属性判断是否是单一绑定配置还是多个实例绑定配置,这里multiple
默认为true
。
这里单一实例和多实例的区别,如下所示,多实例就是协议我可能支持多种,这样会根据我们是否支持多实例来给每个协议都生成一个配置.
1.1.2、AnnotatedBeanDefinitionRegistryUtils#registerBeans
- 上面会根据单实例还是多实例的区别来判断传入的注解类是
DubboConfigConfiguration.Single
还是DubboConfigConfiguration.Multiple.class
,最终都会调用到registerBeans
方法。- 这里会构造一个
AnnotatedBeanDefinitionReader类
,然后会扫描上面传入的注解类,然后注入到spring
容器中。
1.1.3、DubboConfigConfiguration
- 我们上面把
Single or Multiple
注解到spring容器中,然后发现对应类上面也标注了@EnableDubboConfigBindings
注解,二者的区别就是Multiple
多了一个注解属性,multiple
为true
@EnableDubboConfigBindings
注解中是一个@EnableDubboConfigBinding
注解的数组,他的作用就是把配置文件中的配置信息和具体的类进行绑定。
1.1.4、EnableDubboConfigBindings注解
- 这里我们发现他也是通过import导入了一个
DubboConfigBindingsRegistrar
类。
1.1.5、DubboConfigBindingsRegistrar#registerBeanDefinitions
- 上面通过
import
导入了DubboConfigBindingsRegistrar
,他是实现ImportBeanDefinitionRegistrar,spring就会在其生命周期中回调对应的
registerBeanDefinitions`方法。- 这里首先会获取
EnableDubboConfigBindings
注解中的属性列表- 然后获取
value
属性,这里对应就是EnableDubboConfigBinding[]
注解列表- 然后创建了一个
DubboConfigBindingRegistrar
注册器- 把
spring
的环境也就是ConfigurableEnvironment
设置到注册器中,从environment
中可以获取到配置文件中的配置信息- 遍历
EnableDubboConfigBinding[]
注解列表,注册对应的BeanDefinition
1.1.6、DubboConfigBindingRegistrar#registerBeanDefinitions
例:@EnableDubboConfigBinding(prefix = “dubbo.applications”, type = ApplicationConfig.class, multiple = true),
- 这里首先会从
EnableDubboConfigBinding
中解析出来prefix
属性的value
,得到dubbo.applications
- 解析出来
type
属性,得到ApplicationConfig.class
- 解析出来
multiple
属性,得到true
- 把解析出来的参数全部传入调用
registerDubboConfigBeans
注册Dubbo
的配置Bean
1.1.7、DubboConfigBindingRegistrar#registerDubboConfigBeans
- 这里调用
getSubProperties
方法从environment
中,也就是我们配置文件中的配置里面解析出来指定前缀的配置- 如果没有指定前缀的配置则不需要注册
BeanDefinition
- 根据
multiple
属性,这里一般为true
,这样我们如果配置了多种协议,那么就会生成多个beanName
- 给每个
beanName
都注册一个空的BeanDefinition
,然后给每个Bean
都注册一个DubboCOnfigBindingBeanPostProcessor
的bean
的后置处理器- 最后调用
registerDubboConfigBeanCustomizers
注册了一个NamePropertyDefaultValueDubboConfigBeanCustomizer
的bean
1.1.7.1、PropertySourcesUtils#getSubProperties
- 把
propertySources
转成MutablePropertySources
- 调用重载方法
getSubProperties
- 这里就是遍历
PropertySource
,解析出来指定前缀的配置,然后缓存起来返回。
1.1.7.2、DubboConfigBindingRegistrar#resolveMultipleBeanNames
- 这里就是从配置中解析出来beanName。
比如配置是如下:
dubbo.protocols.p1.name=dubbo
dubbo.protocols.p1.port=20880
dubbo.protocols.p1.host=0.0.0.0
这里properties传进来的就是
p1.name=dubbo
p1.port=20880
…
那么解析出来的beanName就是p1
1.1.7.3、DubboConfigBindingRegistrar#registerDubboConfigBean
这里就是通过
BeanDefinitionBuilder
生成一个指定类型的空的beanDefinition
并注册到spring容器中。
1.1.7.4、DubboConfigBindingRegistrar#registerDubboConfigBindingBeanPostProcessor
- 这里为我们刚刚每个注册的配置bean都同样注册一个
DubboCOnfigBindingBeanPostProcessor
类型的的bean后置处理器- 这里首先生成一个
DubboConfigBindingBeanPostProcessor
类型的BeanDefinitionBuilder
- 然后这里会设置构造器参数值,把前缀和beanName都传进去,这里的前缀如:
dubbo.registries.r2
,beanName
如:r2
,这里设置构造器参数的value
,那么spring帮我们创建bean的时候就会调用对应的构造器把参数值传进去- 通过
BeanDefinitionBuilder
生成DubboConfigBindingBeanPostProcessor
的BeanDefinition并
注册到spring容器中。
1.1.7.5、DubboConfigBindingRegistrar#registerDubboConfigBeanCustomizers
这里会注册
namePropertyDefaultValueDubboConfigBeanCustomizer
的bean到spring容器中,这里后续DubboConfigBindingBeanPostProcessor
处理逻辑中会用到。
1.1.7.6、DubboConfigBindingBeanPostProcessor#postProcessBeforeInitialization
- 我们在上面会给每个配置bean都生成一个后置处理器,那么在spring容器的生命周期中就会调用到后置处理器的
postProcessBeforeInitialization
方法,我们来看下DubboConfigBindingBeanPostProcessor
的postProcessBeforeInitialization
方法- 这里会判断beanName是否一致,只处理关联的那个bean
- 这里会调用bind方法从properties中获取值并设置到DubboConfig对象中
- 设置dubboConfig对象的name属性,设置为beanName
1.1.7.7、DubboConfigBindingBeanPostProcessor#bind
- 这里会调用dubboConfigBinder的bind方法,我们看下dubboConfigBinder是啥时候构造出来的,他的bind方法是如何实现数据绑定的。
我们看到在DubboConfigBindingBeanPostProcessor#afterPropertiesSet方法会进行初始化操作,这个方法也是spring提供的回调方法,会在属性设置前调用到这个方法
这里initDubboConfigBinder方法首先会从spring容器中获取DubboConfigBinder类型的bean,如果获取不到就创建默认的也就是DefaultDubboConfigBinder。
- 这里initConfigBeanCustomizers方法会从spring容器中获取DubboConfigBeanCustomizer类型的所有bean实现,这里最少会有一个,之前在DubboConfigBindingRegistrar中注册的namePropertyDefaultValueDubboConfigBeanCustomizer
- 然后设置到configBeanCustomizers属性中,并且会按照order进行排序.
1.1.7.8、DefaultDubboConfigBinder#bind
- 从上面我们知道如果我们没有注入DubboCOnfigBinder,则默认是DefaultDubboConfigBinder
- 这里会创建DataBinder,这个是spring提供的,用来实现数据绑定
- 这里设置忽略无用的属性和不能解析的属性
- 从properties中获取指定前缀的属性
- 把perperties转成MutablePropertyValues,调用dataBinder#bind方法执行绑定操作,这里会把MutablePropertyValues中的配置绑定到dubboConfig中。
1.1.7.9、DubboConfigBindingBeanPostProcessor#customize
- 这里会遍历从spring容器中获取的所有configBeanCustomizers,并调用其customize方法
- 这里如果我们没有配置,默认只有一个NamePropertyDefaultValueDubboConfigBeanCustomizer
这里其实就是判断如果DubboConfig中有name属性,则判断如果name属性如果没有设置值,则反射调用其set方法把beanName设置到name属性中。
1.2、DubboComponentScan注解
这里通过Import导入了DubboComponentScanRegistrar
1.2.1、DubboComponentScanRegistrar#registerBeanDefinitions
- 获取包扫描路径
- 注册处理@Service注解的后置处理器
- 注册处理@Reference注解的后置处理器
1.2.2、DubboComponentScanRegistrar#getPackagesToScan
- 获取DubboComponentScan注解中配置的属性
- 获取value属性,并把包路径数组转成set,可以对重复的包路径去重
- 如果指定了basePackageClasses,那么说明需要对这些类所在包路径设置到set中
- 如果都没指定包路径,则使用当前标注了@DubboComponentScan注解所在类的包路径作为基础包扫描路径。
1.2.3、DubboComponentScanRegistrar#registerServiceAnnotationBeanPostProcessor
- 注册ServiceAnnotationBeanPostProcessor后置处理器到spring容器中,并制定构造器的参数值为包扫描路径,这里spring会在生成bean的时候会调用构造方法设置进去
1.2.4、DubboComponentScanRegistrar#registerReferenceAnnotationBeanPostProcessor
- 注册registerReferenceAnnotationBeanPostProcessor后置处理器到spring容器中
1.2.5、ServiceAnnotationBeanPostProcessor#postProcessBeanDefinitionRegistry
- ServiceAnnotationBeanPostProcessor是一个BeanDefinitionRegistryPostProcessor,spring会回调他的postProcessBeanDefinitionRegistry方法来让用户修改BeanDefinition
- 这里会获取用户注解配置的包扫描
- 调用registerServiceBeans注册ServiceBean
1.2.5.1、ServiceAnnotationBeanPostProcessor#postProcessBeanDefinitionRegistry
这里就是做了下占位符的处理,因为有可能包路径中有占位符例:xxx.${xx}…xxx。
1.2.5.2、ServiceAnnotationBeanPostProcessor#postProcessBeanDefinitionRegistry
- 这里首先创建DubboClassPathBeanDefinitionScanner,用来执行包扫描
- 从registry中解析出BeanNameGenerator
- 设置的DubboClassPathBeanDefinitionScanner的beanNameGenerator为刚刚解析出来的BeanName生成器
- 给scanner设置IncludeFilter,表示只扫描标注了Dubbo中的@Service注解的类
- 遍历包路径,执行扫描操作,把扫描出来的BeanDifinition转换成BeanDefinitionHolder
- 遍历BeanDefinitionHolders,注册ServiceBean
1.2.5.3、ServiceAnnotationBeanPostProcessor#resolveBeanNameGenerator
- 判断如果BeanDefinitionRegistry是SingletonBeanRegistry类型,则获取internalConfigurationBeanNameGenerator返回
- 如果不是SingletonBeanRegistry或者从容器中没有获取到internalConfigurationBeanNameGenerator则使用AnnotationBeanNameGenerator
1.2.5.4、ServiceAnnotationBeanPostProcessor#findServiceBeanDefinitionHolders
- 获取出来packageToScan路径下标注了@Service的BeanDefinition
- 把扫描出来的BeanDefinition转换成BeanDefinitionHolder,Holder中包含BeanDefinition和BeanName
1.2.5.5、ServiceAnnotationBeanPostProcessor#registerServiceBean
- 从beanDefinitionHolde中解析出来对应的beanClass
- 从BeanClass上获取标注的@Service注解信息
- 从beanClass和@Service注解信息中解析出来对应实现的接口的class
- 从从beanDefinitionHolder中获取BeanName,构造ServiceBean的Definition,这个ServiceBean用来存储这个服务提供者的元数据信息
- 生成ServiceBean的BeanName
- 如果没有冲突,则会添加到spring容器中
1.2.5.5、ServiceAnnotationBeanPostProcessor#resolveClass
- 这里从BeanDefinition获取到对应的BeanClassName,然后通过BeanClassName解析出来对应的class对象
1.2.5.6、ServiceAnnotationBeanPostProcessor#resolveServiceInterfaceClass
- 首先拿@service注解中配置的interfaceClass属性,如果没有指定,在判断用户有没有在注解中指定interfaceName,如果指定了,则尝试解析出interfaceName对应的class返回
- 如果注解中没有配置,则获取到当前BeanClass实现的所有接口类,然后获取第一个
1.2.5.6、ServiceAnnotationBeanPostProcessor#buildServiceBeanDefinition
- 首先通过BeanDefinitionBuilder生成一个空的ServiceBean的BeanDefinition
- 这里获取BeanDefinition的propertyValues,然后设置忽略的属性名,因为这些都是对象类型,是我们之前解析配置文件生成的配置类,已经放到spring容器中,需要通过注入的方式特殊赋值
- 给BeanDefinition的propertyValues添加一个PropertyValues是AnnotationPropertyValuesAdapter,这个可以从environment获取对应的配置,后续spring在进行属性注入的时候会自动填充
- 下面就是调用addPropertyReference,这里会从spring容器中找到对应name的bean,然后把对应的bean设置到其属性中
1.2.5.7、ServiceAnnotationBeanPostProcessor#generateServiceBeanName
这里serviceBeanName的生成规则就是拼接了接口名+分组名+版本号生成一个beanName
1.2.5.8、ServiceBean#onApplicationEvent
- 在上面我们已经把ServiceBean注册到Spring容器中,那么他是什么时候进行服务暴露的,注册到注册中上,供外部服务调用,从下图我们可以看到他是继承了很多接口,其中一个就是ApplicationListener,并且监听的是容器刷新完成的时间。
- 那么Spring容器在刷新完成的时候就会回调监听器的onApplicationEvent方法,在这里会进行dubbo服务的导出操作,这个后续我们再进行分析。
1.2.6、ReferenceAnnotationBeanPostProcessor
- 这里他继承了AnnotationInjectedBeanPostProcessor,并且指定了要进行自动注入的注解是@Reference注解,这个AnnotationInjectedBeanPostProcessor的回调时机是在Bean属性填充完毕后,这里可以类比@Autowried注解,也是会有一个xxxProcessor来进行自动注入的逻辑
1.2.6.1 、AnnotationInjectedBeanPostProcessor#postProcessPropertyValues
- 这里首先会找到Bean所有标注了@Reference注解的字段和方法
- 然后对字段、方法进行反射绑定
1.2.6.2 、AnnotationInjectedBeanPostProcessor#findInjectionMetadata
- 这里首先从缓存中获取当前bean的注入元数据信息
- 如果缓存中没有,则会调用buildAnnotatedMetadata方法构造注解元数据
1.2.6.3 、AnnotationInjectedBeanPostProcessor#buildAnnotatedMetadata
- 这里首先查找这个类标注了@Reference注解的属性元素
- 再查找这个类标注了@Reference注解的方法元素
- 组装成AnnotatedInjectionMetadata返回
1.2.6.4 、AnnotationInjectedBeanPostProcessor#buildAnnotatedMetadata
- 这里就是遍历这个类对应的所有属性,判断上面有没有标注@Reference注解
- 判断如果有标注注解,如果修饰符是static,那么也不支持
- 如果满足条件则加入到元素列表中返回
1.2.6.5 、AnnotationInjectedBeanPostProcessor#findAnnotatedMethodMetadata
- 这里遍历类中的所有方法,这里有可能方法是个泛型方法,因为泛型在编译阶段会进行类型擦除,Java编译器会将类型参数替换为其上界(类型参数中extends子句的类型),如果上界没有定义,则默认为Object,当一个子类在继承(或实现)一个父类(或接口)的泛型方法时,在子类中明确指定了泛型类型,那么在编译时编译器会自动生成桥接方法,这样是为了避免子父类方法签名不一致,就在子类自动生成一个与父类的方法签名一致的桥接方法
- 所以这里会判断如果是桥接方法就找到被桥接的方法,然后判断被桥接的方法是否可见,方法上面有没有标注@Reference注解
- 如果有注解,则判断是不是静态,不支持静态方法,也不支持无参方法,因为这样没法进行注入了,不知道注入啥类型的
- 把符合条件的方法收集返回
1.2.6.5 、InjectionMetadata#inject
- 在上面已经查询到了并组装成InjectionMetadata,这里会调用inject方法执行注入操作
- 这里是spring的源码,会遍历每个element,并调用其inject方法
1.2.6.6 、InjectionMetadata#inject
在上面调用每个element的inject方法就会调用到element具体的实现,是方法的还是属性的
1.2.6.6.1 、AnnotatedFieldElement#inject
- 获取属性类型
- 获取注入的对象
- 通过反射设置到属性中
1.2.6.6.2、AnnotatedFieldElement#inject
- 获取属性类型
- 获取注入的对象
- 通过反射设置
1.2.6.7 、AnnotationInjectedBeanPostProcessor#getInjectedObject
- 首先构造缓存key,从缓存中获取
- 如果缓存中不存在,则调用doGetInjectedBean获取注入的对象
1.2.6.8 、ReferenceAnnotationBeanPostProcessor#doGetInjectedBean
- 首先构造serviceBean的名字,通过接口+分组+版本构造
- 调用buildReferenceBeanIfAbsent方法,生成ReferenceBean对象
- 放入缓存中
- 生成代理对象
1.2.6.9 、ReferenceAnnotationBeanPostProcessor#buildReferenceBeanIfAbsent
- 先从缓存中获取referenceBean
- 如果缓存中没有,则通过ReferenceBeanBuilder生成一个referenceBean
1.2.6.9.1 、ReferenceBeanBuilder#build
- 这里checkDependencies是个空方法
- 调用doBuild创建一个ReferenceBean
- 调用configureBean配置ReferenceBean的相关属性
1.2.6.9.2 、ReferenceBeanBuilder#doBuild
- 这里直接创建一个ReferenceBean返回
1.2.6.9.3、AbstractAnnotationConfigBeanBuilder#doBuild
- ConfigureBean的前置操作
- 然后设置注册中心配置,监控中心配置,应用配置,模块配置等
- ConfigureBean的后置操作
1.2.6.9.4、ReferenceBeanBuilder#preConfigureBean
- 这里又使用到了DataBinder来给referenceBean来做数据绑定
- 这里给filter和listener属性注册了StringTrimmerEditor,他会帮助格式化String,去除前后空格
- 处理parameters属性,通过自定义的PropertyEditorSupport,把String处理成map
- 调用dataBinder#bind方法,这里会自动给referenceBean绑定配置文件中的相关配置
1.2.6.9.5、AbstractAnnotationConfigBeanBuilder#configureRegistryConfigs
这里设置配置的逻辑一致,都是从@Reference注解中获取对应的配置名,然后从spring容器中找到对应的配置Bean,然后设置到属性中。
1.2.6.9.6、ReferenceBeanBuilder#postConfigureBean
- 这里还是设置一些属性到ReferenceBean中,其中具体就不细看了,和上面类似
1.2.6.10 、ReferenceAnnotationBeanPostProcessor#cacheInjectedReferenceBean
这里就是把对应的注入点和对应的注入值放入缓存中
1.2.6.11 、ReferenceAnnotationBeanPostProcessor#buildProxy
- 调用buildInvocationHandler方法构造一个InvocationHandler
- 创建一个proxy对象返回,这里需要代理对象是因为Dubbo在调用的时候就算是本地服务也有负载均衡,注册中心等一系列其他的逻辑,因此不能直接返回服务实现类,而是返回代理对象,公共的操作让代理对象去执行
1.2.6.12 、ReferenceAnnotationBeanPostProcessor#buildInvocationHandler
.1 先从缓存中获取,如果缓存中没有就创建一个
2. 判断当前spring容器中有没有包含着这个引用的bean,如果有说明是本地调用,则缓存起来
3. 如果是远程调用,则会调用ReferenceBeanInvocationHandler#init方法
1.2.6.12 、ReferenceBeanInvocationHandler#init
- 这里会调用referenceBean#get方法,会返回一个代理对象
- 这里#referenceBean#get方法是服务引入的核心逻辑,我们后续章节剖析
最后这里返回的代理对象会被设置到对应标注了@Reference的属性中,然后调用其方法都会走到代理对象这里,Dubbo会在这里面做一系列远程调用,服务容错,服务逻辑的逻辑。
相关文章:

spring注解方式整合Dubbo源码解析
系列文章目录 前言 本节我们的Dubbo源码版本基于2.6.x 在前一章我们的整合案例中,我们有几个比较关键的步骤: 在启动类上标注了EnableDubbo注解在provider类上面标注了Service注解来提供dubbo服务在消费的时候通过Reference注解引入dubbo服务在配置文件…...

大数值金额大写转换(C语言)
关于大数值金额大写转换,在财务管理的应用方面没什么意义。一般来说,千亿级,万亿级的数值就够了。因为在国家级层面是以亿为单位的,也就表达为千万亿,万万亿。在企业层面数值金额转换设置到千亿、万亿就行了。大的集团…...

迷宫问题图解 : 基于骨架提取、四邻域
目录 1. 迷宫的连通域 2. How to remove branch ? 3. 基于4邻域的 remove 分支 3.1 找到分支的端点 3.2 4邻域的 remove 分支 3.3 循环移除分支 3.4 code 4. 迷宫路线 4.1 预处理 4.2 提取骨架 4.3 分支的端点 4.4 去除分支的端点 4.5 循环去除分支 4…...

设计模式 - 如何在库和主程序之间互相调用数据和函数
背景:在项目开发过程中,难免碰到这种情况,当我们想要通过我们开发的库,调用主程序中的一些变量或者函数的时候,就会导致一些问题,因为在项目构建过程中,库都是不依赖于主程序编译的,…...

Redis面试题:1~2亿条数据需要缓存,请问如何设计这个存储案例
目录 前言 一、哈希取余分区 优点 缺点 二、一致性哈希算法分区 背景 步骤 ① 算法构建一致性哈希环 ② 服务器IP节点映射 ③ key落到服务器的落键规则 优点 ① 容错性 ② 扩展性 缺点 三、哈希槽分区 前言 单机单台100%不可能,肯定是分布式存储&am…...

程序员必备的软技能-《如何阅读一本书》
阅读很重要,我们真的会阅读吗? 这本书的初版是 1940年,时隔 80年,其内容仍然不过时。第一次读这本书时,给我最大的影响就是主题阅读,每次学习一个新理论、技术,都入手多本关于这项理论、技术的书…...

Java数据结构-栈、队列常用类(Stack、ArrayDeque、LinkedLList)
数据结构的三要素包括:逻辑结构、存储结构、数据的运算。逻辑结构描述的是数据之间的逻辑关系,分为线性结构(线性表(数组、链表)、栈、队列)和非线性结构(图、树、集合)。物理结构也…...

拯救了大批爬虫程序员,因为一个简单的神器
相信大家应该都写过爬虫,简单的爬虫只需要使用 requests 即可。遇到复杂的爬虫,就需要在程序里面加上请求头和参数信息。类似这种:我们一般的步骤是,先到浏览器的网络请求中找到我们需要的请求,然后将请求头和参数信息…...

2023年美赛C题Wordle预测问题三、四建模及Python代码详细讲解
更新时间:2023-2-19 16:30 相关链接 (1)2023年美赛C题Wordle预测问题一建模及Python代码详细讲解 (2)2023年美赛C题Wordle预测问题二建模及Python代码详细讲解 (3)2023年美赛C题Wordle预测问题三、四建模…...

相关性-回忆录(持续更新)
1.TODO方向 (1)数据增强:finetuning阶段需要大量人工标注样本,消耗时间和成本。用户点击数据作为弱监督学习,可以尝试图网络构建节点和边(query聚合); 使用展现未点击生成对抗网络进…...

(必备技能)使用Python实现屏幕截图
(必备技能)使用Python实现屏幕截图 文章目录 (必备技能)使用Python实现屏幕截图 一、序言二、环境配置 1、下载pyautogui包2、下载opencv-python包3、下载PyQt5包4、下载pypiwin32包 三、屏幕截屏源码与解析 1、使用pyautogui方法实现截屏2、使用PyQt方法实现截屏 a.获取窗口…...

「数据仓库」怎么选择现代数据仓库?
构建自己的数据仓库时要考虑的基本因素我们用过很多数据仓库。当我们的客户问我们,对于他们成长中的公司来说,最好的数据仓库是什么时,我们会根据他们的具体需求来考虑答案。通常,他们需要几乎实时的数据,价格低廉&…...

6.3 使用 Swagger 生成 Web API 文档
第6章 构建 RESTful 服务 6.1 RESTful 简介 6.2 构建 RESTful 应用接口 6.3 使用 Swagger 生成 Web API 文档 6.4 实战:实现 Web API 版本控制 6.3 使用 Swagger 生成 Web API 文档 高质量的 API 文档在系统开发的过程中非常重要。本节介绍什么是 Swaggerÿ…...

Day894.加锁规则的一些问题 -MySQL实战
加锁规则的一些问题 Hi,我是阿昌,今天学习记录的是关于加锁规则的一些问题的内容。 加锁规则,这个规则中,包含了两个“原则”、两个“优化”和一个“bug”: 原则 1:加锁的基本单位是 next-key lock。nex…...

【Flutter入门到进阶】Dart进阶篇---Dart异步编程
1 并行与并发的编程区别 1.1 并发与并行 1.1.1 说明 我们举个例子,如果有条高速公路 A 上面并排有 8 条车道,那么最大的并行车辆就是 8 辆此条高速公路 A 同时并排行走的车辆小于等于 8 辆的时候,车辆就可以并行运行。 CPU 也是这个原理,一个 CPU 相当于一个高速公路 A,核心数…...

点云配准方法原理(NDT、ICP)
配准是点云处理中的一个基础问题,众多学者此问题进行了广泛而深入的研究,也出现了一系列优秀成熟的算法,在三维建模、自动驾驶等领域发挥着重要的作用。 本文主要介绍粗配准NDT (Normal Distribution Transform) 与 精配准ICP (Iterative Cl…...

大规模 IoT 边缘容器集群管理的几种架构-0-边缘容器及架构简介
📚️Reference: IoT 边缘计算系列文章 什么是边缘容器? 边缘容器的概念 边缘容器是分散的计算资源,尽可能靠近最终用户或设备,以减少延迟、节省带宽并增强整体数字体验。 可以访问互联网的设备数量每天都在增加。有包括但不限于…...

代码随想录算法训练营第45天动态规划 背包基础 1 2、 416. 分割等和子集
文章目录01背包基础 (二维数组)思路递推公式初始化遍历顺序一维dp数组(滚动数组)一维数组的递推公式遍历顺序LeetCode 416. 分割等和子集思路总结01背包基础 (二维数组) 思路 根据动态规划五部进行分析&a…...

QT学习记录(六)类对象属性
类对象属性用来描述类对象的一些信息和当前的状态。类对象属性可以由类的编写者在编写类的时候定义,也可以由类的使用者在使用对象的时候定义。 由类的编写者定义 QPROPERTY()宏就是用来定义一个对象属性。 以第二行属性举例 QPROPERTY(bool enabled READ isEnabl…...

Spring Cloud Alibaba从搭建到源码完整进阶教程
微服务简介 Spring Cloud Alibaba 微服务简介 Nacos注册中心配置中心 Spring Cloud Nacos实战(一)- 下载和安装 Spring Cloud Nacos实战(二)- 服务提供者注册 Spring Cloud Nacos实战(三)- 服务消费者…...

Spring Cloud Nacos实战(一)- 下载和安装
Spring Cloud Alibaba Nacos下载和安装 Nacos介绍 Nacos(Naming Configuration Service) 是一个易于使用的动态服务发现、配置和服务管理平台,用于构建云原生应用程序 服务发现是微服务架构中的关键组件之一。Nacos 致力于帮助您发现…...

深入理解设备像素比
文章目录参考描述像素分辨率显示分辨率图像分辨率物理分辨率分辨率单位(仅部分)DPIPPI设备像素比设备物理像素设备独立像素设备像素比产生放大与缩小尾声参考 项目描述关于物理像素、逻辑像素(css像素)、分辨率、像素比的超详细讲…...

Revisiting Distributed Synchronous SGD 带有Back-up机制的分布式同步SGD方法 论文精读
论文链接:Revisiting Distributed Synchronous SGD ABS 本文介绍了用于分布式机器学习的同步和异步SGDSGDSGD,同时指出各自的缺点:stragglersstragglersstragglers和stalenessstalenessstaleness。 同时为了解决同步SGDSGDSGD存在straggle…...

shiro CVE-2020-13933
0x00 前言 同CVE-2020-1957,补充一下笔记,在CVE-2020-1957的基础上进行了绕过。 影响版本:Apache Shiro < 1.6.0 环境搭建参考:shiro CVE-2020-1957 0x01 漏洞复现 CVE-2020-13933中使用%3b绕过了shiro /*的检测方式&…...

斐波那契数列(递归+迭代)
目录什么是斐波那契数列递归写法使用递归写法的缺点迭代写法(效率高)什么是斐波那契数列 斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多斐波那契(Leonardo Fibonacci)以兔子繁殖为例…...

2022黑马Redis跟学笔记.实战篇(六)
2022黑马Redis跟学笔记.实战篇 六4.7.达人探店功能4.7.1.分享探店图文1. 达人探店-发布探店笔记2. 达人探店-查看探店笔记4.7.2.点赞功能4.7.3.基于List实现点赞用户列表TOP104.7.4.基于SortedSet实现点赞排行榜4.8.关注列表4.8.1.关注列表实现原理4.8.2.添加关注1. 好友关注-关…...

Linux-VMware常用设置(时间+网络)及网络连接激活失败解决方法-基础篇②
目录一、设置时间二、网络设置1. 激活网卡方法一:直接启动网卡(仅限当此)方法二:修改配置文件(永久)2. 将NAT模式改为桥接模式什么是是NAT模式?如何改为桥接模式?三、虚拟机网络连接…...

vue3学习总结1
一.vue3与vue2相比带来哪些变化?a.性能的提升(包括打包大小减少,初次渲染的速度加快,更新渲染速度加快,内存减少)b.源码的升级(响应式的原理发生了变化,由原来的defineProperty变成了…...

SpringBoot统一功能处理
一、统一用户登录权限验证 1.1Spring拦截器 实现拦截器需要以下两步: 1.创建自定义拦截器,实现 HandlerInterceptor 接⼝的 preHandle(执行具体方法之前的预处理)方法。 2.将⾃定义拦截器加⼊ WebMvcConfigurer 的 addIntercept…...

2022年3月电子学会Python等级考试试卷(五级)答案解析
目录 一、单选题(共25题,共50分) 二、判断题(共10题,共20分) 三、编程题(共3题,共30分) 青少年软件编程(Python)等级考试试卷(五级&#...