Refresh解析

news2024/11/11 3:22:18

目录

后置处理器PostProcessor

PostProcessor的种类

Aware

事件监听模式

Spring容器的刷新逻辑

ApplicationContext refresh的流程概述

1---prepareRefresh

2---obtainFreshBeanFactory

3---prepareBeanFactory

4---postProcessBeanFactory

5---invokeBeanFactoryPostProcessors

6---registerBeanPostProcessors

7---initMessageSource

8---initApplicationEventMulticaster

9---onRefresh

10---registerListeners

11---finishBeanFactoryInitialization

12---finishRefresh

小结


  • 后置处理器PostProcessor

  • 本身也是一种需要注册到容器里的Bean
    • 其里面的方法会在特定的时机被容器调用
    • 实现不改变容器或者Bean核心逻辑的情况下对Bean进行扩展
    • 对Bean进行包装,影响其行为、修改Bean的内容等
  • PostProcessor的种类

  • 大类分为容器级别的后置处理器以及Bean级别的后置处理器
    • BeanDefinitionRegistryPostProcessor
    • BeanFactoryPostProcessor
    • BeanPostProcessor
  • 前两个是容器级别的处理器,最后一个是Bean级别的处理器
  • BeanDefinitionRegistryPostProcessor
    • 负责自定义的BeanDefinition的注册;允许在正常的BeanFactoryPostProcessor检测开始之前注册更多的自定义beanDefinition

  • 继承BeanFactoryPostProcessor,可以看成是一种特殊的BeanFactoryPostProcessor;他只有一个方法
  • 方法展示:
  • 创建BeanDefinition实例,再将其注册到形参register里面
  • 编写实现类;要先将其实现类注入到容器里,才能和容器对话

  • main函数中获得我们刚注册的bean实例

  • BeanFactoryPostProcessor:影响容器的行为
  • BeanPostProcessor:
  • 对于每个由容器创建的bean实例,BeanPostProcessor都会在调用容器初始化之前以及在任何bean初始化回调之后,都从容器获得回调执行;注意不是BeanDefinition实例
  • 方法展示:

  • 在main函数执行发现每一个Spring管理的bean都会去执行那两个方法,且先执行before再after

  • 可以使用BeanPostProcessor的能力对bean进行包装即在bean创建之后在postProcessAfterInitialization对bean包装统一的逻辑,比如耗时统计的日志记录,之后再返回增强的bean
  • 在源码中在逐个执行排序好的postprocessors时,采用责任链模式来执行,每个接收者都包含对另外一个接收者的引用;如果一个对象不能处理该请求,会把该对象转发给下一个接收者,以此类推
  • Aware

  • 容器对bean本身的逻辑是无侵入的,因此bean不需要了解容器的状态可直接使用容器
  • 但在某些情况下需要在bean中对容器进行直接操作的,这时就需要在bean中设置对容器的感知了,这便是Aware接口的作用
  • 这个接口里面什么方法都没有,所以只能当作标签来使用
  • ApplicationContextAware

  • 在容器创建这个bean实例的时候,将容器本身的实例作为参数传进来给这个bean来使用
  • BeanFactoryAware:获取当前的BeanFactory,这样就可以调用容器的服务
  • ApplicationEventPublisherAware:获取发布器实例已发布的事件
  • 想实现什么功能就调用相关接口
  • 例:获取注册到这个容器里的所有beandefinition的name

  • main函数

  • 注意:想要获取容器提供的资源,除了继承Aware接口之外,类本身还是要被Spring容器管理的bean才行
  • 事件监听模式

  • 回调函数
  • 往组件注册自定义的方法以便组件在特定场景下调用
  • Thread类就是组件,run()方法就是回调函数,我们并不希望直接调用Runnable里面的run方法
  • 而是希望Thread组件在某个时刻去执行它,该时刻就是在调用start方法之后再去执行
  • 事件监听器模式

  • 监听器将监听感兴趣的事件,一旦事件发生,便做出响应
  • 事件源( Event Source ):比如说一个按钮,要想使某个按钮对某个事件做出响应,就需要监听器
  • 事件监听器( Event Listener ):需要注册到事件源上才能被调用,主要用来监听事件并进行事件处理或者转发
  • 事件对象( Event Object ):负责事件源和事件监听器之间的信息传递
  • 例子:
  • 1---创建事件

  • 2---创建事件监听器

  • 实现类

  • 3---创建事件源
  • 因为需要将事件监听器注册到事件源里,事件监听器有多个,所以需要定义一个List集合
  • 提供一个共有的方法供外界输入数据,还有输出数据即发布事件的方法
  • 主要发布给listener,遍历所有的listener,都发一个事件,listener再去处理事件

  • 还需要将lisener注册到事件源里面,注册好之后,事件源去发布事件,交给事件监听器去处理

  • 使用事件监听器模式可以解耦,事件监听器和事件源是可以分开开发的
  • 其中只有事件作为联系,不用关心另一方怎么实现的,事件监听器其实是观察者模式的一种实现
  • 事件源组件和事件等于观察者的主题主键类似,事件监听器对标观察者模式的观察者
  • Spring的事件驱动模型

  • 事件驱动模型的三大组成部分
    • (一)事件:ApplicatinEvent抽象类

    • 继承自jdk的EventObject,所有事件将继承于ApplicatinEvent,并通过里面的source成员变量获得事件
    • 事件源就是发布事件的地方,这里指的就是容器本身
    • ApplicationEvent并不单单指的是容器事件,为了专门给容器定制事件,产生了ApplicationContextEvent子类,用来表示容器事件
    • 下面是框架对其的实现类
    • 在容器中发布一个任意类型的事件之后,会被自动封装为PayloadApplicationEvent类

    • (二)事件监听器 : ApplicationListener

    • 用户可以实现此接口,实现里面的方法实现自定义监听器;也可以使用注解的方式对类进行监听
    • 这样就可以将该类晋升为监听器,同时使用sayHello方法进行监听

    • SmartApplicationListener
    • 继承order,可以给事件排序

    • 判断事件类型和事件源类型是否和当前监听者匹配,这样监听者就可以筛选自己感兴趣的事件或者事件源

    • GenericApplicationListener

    • ResolvableType:获取泛型信息的工具,可以通过它获得泛型的任何信息类似于反射

    • (三)事件发布器 : Publisher以及Multicaster
    • 可以在bean里面通过Aware获得ApplicationEvnetPublisher实例,其实也就是获得容器这个实例
    • 就可以发布自定义的事件给容器里注册的自定义的eventListener去处理

    • 发现容器ApplicationContext继承ApplicationEventPublisher

    • ApplicationEventPublisher

    • 它里面的两个方法都是用来发布事件的,即这个接口只能用来发布事件
    • ApplicationEventMulticaster
    • 有添加和删除listener、发布的功能

    • Executor:执行器,说明它支持多线程去处理监听器的方法
    • 为什么需要ApplicationEventPublisher和ApplicationEventMulticaster这两个接口?
    • 既然ApplicationEventMulticaster已经具有了所有的功能,为什么不直接使用它替代掉ApplicationEventPublisher?
    • 比如说像bean容器本身(applicationcontext)就只想发布事件,而不想维护事件监听器这些
    • 所以Spring将事件源做了进一步分割,抽象出事件发布器接口,将ApplicationEventMulticaster作为代理
    • 就像applicationcontext用我们的DefaultListableFactory作为代理一样,让ApplicationEventPublisher的实现类来实现publishEvent里面的逻辑
    • 那ApplicationEventPublisher里面就主要实现调用ApplicationEventMulticaster实现类的multicastEvent来发布事件就可以了
  • Spring容器的刷新逻辑

  • 刷新的意思就是将BeanFactory清空为初始状态,然后再按照程序意图填满各种bean实例
  • 注解的beanDefinition注册时,DefaultListableBeanFactory这个实例已经在注册主键类之前,也就是调用容器的构造函数时就已经创建了
  • 后置器ApplicationContextAwareProcessor:当bean实例继承ApplicationContextAware接口时,去给这些bean实例注入ApplicationContext对象
  • 调用完了容器级别的后置处理器之后,接下来就是bean级别的后置处理器
  • register这一步就是将先前定义的bean级别的后置处理器给注册到容器里,方便后续在调用getBean方法去创建bean实例时,在特定的环节去触发这些后置处理器执行一些特定的逻辑,比如AOP织入
  • 初始化事件发布器:用来接收实现ApplicationEventPublisher接口类发送过来的不同的事件,并派给不同的事件监听者进行处理
  • onRefresh():钩子方法,用于初始化其他特殊的bean,发生在单例的bean初始化之前去执行
  • 往先前已经初始化出来的ApplicationEventMulticaster去注册相关的监听器,用来监听不同的事件

  • ApplicationContext refresh的流程概述

  • ApplicationContext是Spring中的核心容器,refresh是ApplicationContext的一个方法,主要作用是用来初始化ApplicationContext
  • refresh一共分为十二个步骤
  • 所有的ApplicationContext有一个共同的父类叫AbstractApplicationContext
  • 这个父类里有refresh方法,这个方法里面有12个比较重要的方法

  • (1)蓝色:代表做一些准备工作
  • (2—6)绿色:创建并准备BeanFactory对象
  • 为什么需要BeanFactory对象呢?
  • 因为ApplicationContext只是一个外部容器,核心功能还需要交给BeanFactory来完成(Bean的创建、Bean的依赖注入、Bean的初始化)
  • (7—12)黄色:准备ApplicationContext,为ApplicationContext里面一些特有的功能做一些准备
  • (11)红色:比较重要,是在创建和初始化单例对象;容器当中的单例对象都是在第11步创建并初始化完成的
  • 1---prepareRefresh

  • 要点
    • 这一步创建和准备了Environment对象
    • 要理解Environment对象的作用
  • prepareRefresh主要就是准备了一个Environment对象,这个环境对象后续的代码里都会用到
  • 他就是为Spring后续运行时提供一些键值信息
  • systemProperties:java中的一些键值(java中的默认编码、文件分割符等)
  • systemEnvironment:提供了操作系统的键值对(java_home、path、classPath等)
  • 自定义:从自定义的properties文件当中的读取到的信息;例如application.properties文件
  • 即Environment的作用就是管理各种键值信息,将来其他地方可以用到这些信息,例如@Value
  • 2---obtainFreshBeanFactory

  • 作用:初始化beanFactory,加载并解析配置

  • 方法中做了二件事:
    • refreshBeanFactory():创建beanFactory、指定序列化Id、定制beanFactory、加载bean定义
    • getBeanFactory():返回beanFactory实例
  • refreshBeanFactory()方法主要执行:
    • 如果有bean工厂,销毁bean以及关闭bean工厂
    • createBeanFactory():创建beanFactory
    • beanFactory.setSerializationId(getId()):指定序列化Id
    • customizeBeanFactory():定制BeanFactory
    • loadBeanDefinitions():加载bean定义
  • 3---prepareBeanFactory

  • 作用:配置工厂的标准上下文特征,为beanFactory设置类加载器、后置处理器等
  • 方法逻辑梳理如下:
    • 设置类加载器,默认是RestartClassLoader;
    • 设置表达式解析器StandardBeanExpressionResolver,比如SPEL语法就是该解析器内维护的SpelExpressionParser进行处理的;
    • 向Set<PropertyEditorRegistrar> propertyEditorRegistrars 添加 ResourceEditorRegistrar;
    • 注册beanPostProcessor如ApplicationContextAwareProcessor;
    • 向Set<Class<?>> ignoredDependencyInterfaces中添加对象如EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware;也就是说这些类将不会通过Autowired自动注入而是会被BeanFactory通过比BeanFactoryAware或者ApplicationContext通过ApplicationContextAware这种方式设置
    • 向Map<Class<?>, Object> resolvableDependencies放入BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext;表示是已经解析的依赖可以直接使用
    • 注册应用监听器检测器,如果实例化bean是ApplicationListener,则其将会被放入applicationListeners;
    • 如果 loadTimeWeaver 存在于beanFactory,则注册LoadTimeWeaverAwareProcessor并设置TempClassLoader为ContextTypeMatchClassLoader
    • 注册默认的环境信息bean如environment、systemProperties、systemEnvironment
  • 4---postProcessBeanFactory

  • Spring中并没有具体去实现postProcessBeanFactory方法,是提供给想要实现BeanPostProcessor的三方框架使用的
  • 谁要使用谁就去实现
  • 作用是在BeanFactory准备工作完成后做一些定制化的处理,一般结合BeanPostProcessor接口的实现类一起使用,注入一些重要资源(类似Application的属性和ServletContext的属性)
  • 最后需要设置忽略这类BeanPostProcessor子接口的自动装配
  • 是一种模板方法的设计模式,refresh方法的主要脉络都被父类给规定死了,但是有一些可以扩展的方法把它留空,将来有子类去实现
  • 5---invokeBeanFactoryPostProcessors

  • 主要用来调用beanFactory后置处理器来修改beanDefinition
  • 该方法实例化并调用已经注册到beanFactory的beanFactoryPostProcessor实例
  • BeanFactory有两个扩展点,第一处就是交给子类去扩展,第二处就是交给bean的后置处理器
  • 6---registerBeanPostProcessors

  • 本方法会注册所有的 BeanPostProcessor,将所有实现了 BeanPostProcessor 接口的类加载到 BeanFactory 中
  • BeanPostProcessor 接口是 Spring 初始化 bean 时对外暴露的扩展点,Spring IoC 容器允许 BeanPostProcessor 在容器初始化 bean 的前后,添加自己的逻辑处理
  • 在 registerBeanPostProcessors 方法只是注册到 BeanFactory 中,具体调用是在 bean 初始化的时候
  • 具体的:在所有 bean 实例化时,执行初始化方法前会调用所有 BeanPostProcessor 的 postProcessBeforeInitialization 方法,在执行初始化方法后会调用所有 BeanPostProcessor 的 postProcessAfterInitialization 方法
  • 7---initMessageSource

  • 主要用于国际化,说简单点就是不同语言之间的翻译
  • 该方法将会初始化MessageSource并尝试设置parentMessageSource,然后作为单例bean注册到容器中
  • 通常注册是 DelegatingMessageSource 实例
  • 8---initApplicationEventMulticaster

  • 该方法主要完成事件管理类的初始化,并加入一级缓存
  • 初始化ApplicationEventMulticaster事件,默认使用SimpleApplicationEventMulticaster事件

  • 9---onRefresh

  • onRefresh()方法是Spring预留给子类,用于初始化其他的Bean用的
  • 例:Spring中 AbstractApplicationContext onRefresh()的是没有做任何事情的
  • 而在Spring Boot中 ServletWebServerApplicationContext onRefresh()是有重写这个方法的

  • 其中super.onRefresh()为GenericWebApplicationContext onRefresh()

  • 这一步是初始化主题功能
  • 10---registerListeners

  • 方法主要将实现监听器接口(即ApplicationListener接口)的bean们注册到多播器中,即存储到applicationListenerBeans集合中
  • 代码分为三个步骤:
    • 1.注册硬编码方式的监听器
    • 2.注册配置文件的监听器
    • 3.发布需要进行发布的事件
  • 11---finishBeanFactoryInitialization

  • 该方法会实例化所有剩余的非懒加载单例 bean
  • 除了一些内部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,其他的非懒加载单例 bean 都会在这个方法中被实例化,并且 BeanPostProcessor 的触发也是在这个方法中
  • 代码步骤:
    • 1.初始化此上下文的转换服务
    • 2.如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析
    • 3.初始化LoadTimeWeaverAware Bean实例对象
    • 4.冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了
    • 5.实例化所有剩余(非懒加载)单例对象
  • 12---finishRefresh

  • 完成上下文的刷新工作,包括初始化LifecycleProcessor,发布刷新完成事件等
  • 方法功能梳理:
    • 清理前面记录的类资源(因为已经有了BeanDefinition)
    • 初始化生命周期处理器,默认是DefaultLifecycleProcessor,并作为单例注册到容器
    • 触发DefaultLifecycleProcessor的onRefresh方法,简单来讲就是触发那些实现了Lifecycle的bean的start方法并将running状态设置为true
    • 发布事件ContextRefreshedEvent,标志着上下文刷新执行完毕
    • 注册ApplicationContext到LiveBeansView内部的applicationContexts中
    • 启动webserver,处理webserver的service与connector,并触发connector的start方法
    • 发布ServletWebServerInitializedEvent事件,标志着WebServer启动完毕
  • 小结

  • 1.prepareRefresh---做好准备工作(创建Environment对象,为Spring后续的运行提供一些键值信息)
  • 2.obtainFreshBeanFactory ---创建或获取BeanFactory
  • 3.prepareBeanFactory ---准备BeanFactory(为BeanFactory创建各个成员变量,EL表达式解析器、类型转换器、内置的BeanPostProcessor)
  • 4.postProcessBeanFactory ---子类扩展BeanFactory
  • 5.invokeBeanFactoryPostProcessors ---后处理器扩展BeanFactory(Bean工厂的后置处理器:ConfigurationClassPostProceessors,解析配置类的注解:@Configuration、@Bean等)
  • 6.registerBeanPostProcessors ---准备Bean后处理器(常见的有三个,一个是解析@Autwired注解,一个是解析@Resource、一个是解析@Aspect,创建代理类的)
  • 7.initMessageSource ---为ApplicationContext提供国际化功能
  • 8.initApplicationEventMulticaster ---为ApplicationContext提供事件发布器
  • 9.onRefresh ---留给子类扩展
  • 10.registerListeners ---为ApplicationContext准备监听器
  • 11.finishBeanFactoryInitialization ---初始化单例Bean,执行Bean后处理器扩展
  • 12.finishRefresh ---准备生命周期管理器,发布ContextRefreshed事件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/594608.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【正点原子STM32连载】 第二十一章 通用定时器实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html 第二十…

海康萤石摄像头本地局域网拉流保存

海康萤石的视频cp1型号&#xff0c;获取局域网的视频流&#xff1a;rtsp 拉流方法 首先需要在软件中打开rtsp开关&#xff0c;然后使用nmap工具测试下摄像头开放的端口号&#xff0c;一定会有一个554端口开放 $ nmap 192.168.0.105 PORT STATE SERVICE 554/tcp open r…

什么是Flink CDC,以及如何使用

什么是Flink CDC&#xff0c;以及如何使用 CDC介绍Flink CDC适用于场景&#xff1f;Flink CDC 的简单用例数据库配置创建数据库和相应的表开启mysql数据库bin-log日志1.如果是服务器2.如果在Windows使用小皮 搭建Flink CDC java环境添加maven相关pom构建Sinkmain配置运行 操作数…

盘点中国开发的有影响力的编程技术产品,道阻且长,行则将至

计算机诞生之后&#xff0c;程序员需要给计算机发送指令&#xff0c;能够准确地定义计算机所需要使用的数据&#xff0c;并精确地定义在不同情况下所应当采取的行动。计算机需要能够识别并执行指令。这个“指令”就是我们今天的“编程语言”&#xff0c;一种计算机和人都能识别…

【十】设计模式~~~结构型模式~~~享元模式(Java)

【学习难度&#xff1a;★★★★☆&#xff0c;使用频率&#xff1a;★☆☆☆☆】 5.1. 模式动机 面向对象技术可以很好地解决一些灵活性或可扩展性问题&#xff0c;但在很多情况下需要在系统中增加类和对象的个数。当对象数量太多时&#xff0c;将导致运行代价过高&#xff0…

路径规划算法:基于自私羊群优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于自私羊群优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于自私羊群优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化…

图解max{X,Y}和min{X,Y}并求相关概率

图解max{X,Y}和min{X,Y}并求相关概率 对max{X,Y}或min{X,Y}进行分解再求解 P ( m a x { X , Y } ≥ c ) P [ ( X ≥ c ) ∪ ( Y ≥ c ) ] P ( m a x { X , Y } ≤ c ) P [ ( X ≤ c ) ∩ ( Y ≤ c ) ] P ( m i n { X , Y } ≥ c ) P [ ( X ≥ c ) ∩ ( Y ≥ c ) ] P ( m i…

2022年12月1日郑州大学新闻与传播学院副院长博导郑*侠—社科申报注意事项

郑老师&#xff08;1项重点社科&#xff0c;2项青年社科&#xff09;&#xff0c; 一、选题 随时关注 最新国家层面信息&#xff1a;二十大报告&#xff0c;重要文件&#xff0c;重点项目信息 选题方向&#xff1a;问题导向 时代问题—学术问题—现实问题 题目命名&#xf…

基于微信小程序的社区生活管理

一&#xff1a;系统使用到的技术栈 SSMJSP原生JSMysql微信小程序 二&#xff1a;表结构 三&#xff1a;功能截图 四.源码获取

【工具学习】- Python通过dxfgrabber库获取CAD信息

Python - dxfgrabber库获取CAD信息 &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f3c6; 一个有梦有戏的人 怒放吧德德 &#x1f31d;分享学习心得&#xff0c;欢迎…

如何利用Stable Diffusion WebUI快速制作漫画开源

今天给大家带来的是如何利用Stable Diffusion WebUI快速制作漫画。 欢迎大家可以关注我的公众号《乔说科技》&#xff0c;关于如何制作动漫前置学习&#xff0c;请点击如下文章查看相关技术&#xff1a; &#xff08;1&#xff09;如何安装绘图工具Stable Diffusion WebUI&…

2023 手术机器人现状

先看一下主要分类&#xff1a; 手术机器人总览&#xff0c;看一下这张图&#xff1a; 先简单说一下国外的&#xff1a; 1 . 达芬奇手术机器人 简单地说&#xff0c;达芬奇机器人就是高级的腹腔镜系统。大家可能对现在流行的微创治疗手段如&#xff1a;胸腔镜、腹腔镜、妇科腔…

dubbo 3.2.0 token-有bug慎用

dubbo3 provider可以配置token dubbo: application: name: merge-provider-1 qos-enable: false protocol: name: dubbo port: 20880 registry: address: zookeeper://${zookeeper.address:192.168.157.151}:2181 provider: token: “true” 当token 配置为true的时候&#x…

Electron25集成Vue3新建多开窗口|vite4+electron窗体管理器

继上一次分享electron24vite4整合构建桌面端窗口应用。这次在此基础上分享封装多开窗口管理器ElectronVite-MultiWin。 https://blog.csdn.net/yanxinyun1990/article/details/130944508 截至目前Electron最新稳定版本到25了。 electron快速迭代更新&#xff0c;vite的高效构建…

dubbo 3.2.0 merge模式及 adaptive class 生成过程

MergeInvoker生成过程分析 dubbo 3.2.0 merge模式是汇聚多个group内相同服务的返回&#xff0c;核心MergeInvoker代码在public class RegistryDirectory extends DynamicDirectory 内的如下函数。 private List<Invoker<T>> toMergeInvokerList(List<Invoker&…

Spring整合Mybatis框架开发步骤分析

文章目录 1.导入坐标2.配置SpringConfig类3.配置jdbc配置类4.配置MybatisConfig配置类5. xml配置与注解配置之间的转换对比 1.导入坐标 先将依赖坐标导入pom文件中、里面包括spring-context、druid、mybatis、mysql-connector-java、 spring开放出接口标准&#xff0c;如想和…

Redis6 数据结构Hash

前言 在Redis中&#xff0c;hashtable 被称为字典&#xff08;dictionary&#xff09;,它是一个数组链表到结构。每个键值对都会有一个dictEntry OBJ_ENCODING_HT 这种编码夯实内部才是真正的哈希表结构&#xff0c;或称为字典结构&#xff0c;其可以实现O(1)复杂度的读写操作…

深度学习进阶篇[7]:Transformer模型长输入序列、广义注意力、FAVOR+快速注意力、蛋白质序列建模实操。

【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍&#xff1a;【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化…

MP3 Module 语音播放模块(Arduino和串口控制)

MP3 Module 语音播放模块&#xff08;Arduino和串口控制&#xff09; 前言电气参数原理图MP3文件所放位置和命名规则&#xff1a;接线代码串口控制通讯指令&#xff08;部分&#xff09;实验结果 前言 Emakefun MP3语音模块内置8 MB存储空间&#xff0c;无需外接SD卡&#xff…

acwing提高——迭代加深+双向dfs+IDA*

1.迭代加深 顾名思义说明迭代的层数逐渐加深&#xff0c;这样做法有点像bfs的做法层层突出&#xff0c;符合的题型是答案在层数较低的那一层里 加成序列 题目https://www.acwing.com/problem/content/description/172/ #include<bits/stdc.h> using namespace std; c…