Dubbo第三讲:Dubbo的可扩展机制SPI源码解析

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Dubbo第三讲:Dubbo的可扩展机制SPI源码解析

1、Dubbo SPI机制

1.1、Dubbo具有良好拓展性的原因
  • 1、整个框架中针对不同的场景,恰到好处地使用了各种设计模式
  • 2、基于Dubbo SPI 加载机制,让整个框架的接口和具体实现完全解耦合
  • Dubbo SPI 扩展
  • 与Java SPI类似,需要在META-INF/dubbo/下放置对应的SPI配置文件,文件名称需要命名为接口的全路径名。配置文件的内容为 key=扩展点实现类全路径名,如果有多个实现类则需要使用换行符分割
  • 在Dubbo启用时,会默认扫描这三个目录下的配置文件:META-INF/services/、META-INF/dubbo/、META-INF/dubbo/internal/
  • 1、dubbo filter详解
  • todo
1.2、Dubbo SPI和Java SPI的区别?

Dubbo的扩展点加载从JDK标准SPI(Service provider Interface)扩展点发现机制加强而来。

改进了JDK标准SPI的以下问题:

1、JDK标准的SPI会一次性实例化扩展点所有实现,如果有扩展实现初始化很耗时,但是没用上也加载,会很浪费资源。(我的代码中初始化配置项也存在这样的问题)

2、如果扩展点加载失败,连扩展点的名称都拿不到了

3、增加了对扩展点IOC和AOP的支持,一个扩展点可以直接setter注入其他扩展点。

1.3、Dubbo SPI可认为是IOC实现吗?

todo

2、SPI机制在商品中心的应用

2.1、TMF校验器

详情见这个项目

项目实战第十六讲:使用开闭原则实现商品价格规则引擎

2.2、在AfterImage应用中的使用
2.2.1、整体流程图如下所述

2.2.2、业务逻辑

残影系统,使用切面实现的

  • 注解:Afterimage
  • 包含的字段有
  • captorConfig 本次使用的captor(捕获)配置
  • 该类包含两字段 Captor,dubbo接口或其他 config dubbo接口详情,具体结构见下文
  • expireMills 超时时间,单位是毫秒,小于1:不过期;大于1:过期;不配置:使用captor侧配置的过期时间
  • 使用场景:缓存dubbo调用结果,用于优化在执行上下文重复同一dubbo调用
  • 当同个线程执行链路,多次使用此注解时,只有最外层的注解生效
  • 加上此注解的方法,耗时调用将被暂存起来,直到退出方法
  • 注意事项:
  • 必须使用在能被spring AOP代理的方法上
  • 如何使用:
  • 引入依赖
<dependency>
    <groupId>cn.gov.zcy</groupId>
    <artifactId>afterimage-integration-zcy</artifactId>
    <version>2.0.0-SNAPSHOT</version>
</dependency>
  • 如果是spring,请使用注解@EnableAfterimage开启, 然后在需要的方法(可被spring aop切面)加上注解@Afterimage开启。
  • eg: 1、启动时开启Afterimage,如果是spring boot 环境,会自动配置开启,
  • 如果spring-boot,不想启动时自动开启可配置afterimage.spring.bootstrap.enabled=false
@EnableAfterimage
public class Application{
}
  • 开启后,使用在需要优化的方法(可被spring aop切面),使被注解的方法开启afterimage
  • 如果想在运行时关闭,请配置:afterimage.spring.enabled=false
public class ItemServiceImpl{
    @Afterimage
    public Item find(){        
    }
}
  • 执行流程
  • 1、afterimage-config 以扩展配置读取、监听的扩展
  • 第一块:apollo配置获取,监听事件变更
  • 第二块:spring配置 ,将残影实例自动配置到Spring中
  • config 扩展
  • 作用:统计每个dubbo方法的缓存时间
  • 定义的方法:default get(key,defaultValue)、get(key)、default ddListener(key,configListenr) 如果对应key发生变化,调用listener、default removeListener(configListenr) 移除监听器、default removeListener(key, configListenr) 移除监听器
  • 实现类1
  • ApolloConfig(apollo配置)
  • 继承apollo的ConfigChangeListener接口实现了ApolloListener,实现其onChange事件
  • onChange方法里面,遍历所有改变的key,如果等于当前key,监听其改变
  • 补充了addListener方法和removeListener方法
  • 使用了写时复制ArraySet,因为配置读取的场景读多写少
  • 组合apolloConfig,并实现了Config的get方法,底层调用apolloConfig的getProperty方法
  • 实现了addListener(key,configListenr)方法,先创建监听,然后添加监听,如果apolloListener监听的数量等于1,底层调用apolloConfig的addChangeListener方法
  • 实现类removeListener(configListenr)方法,apolloListener移除监听,检查ApolloListener,为空则移除
  • 实现类removeListener(key, configListenr)方法,获取apolloListener监听器,如果为空,返回,否则,移除监听器,检查ApolloListener,为空则移除
  • 实现类2
  • SpringConfig(Spring配置)
  • 先实例化自身,然后获取系统参数
  • 实现了get(key)方法,如果系统参数为空,抛错,否则,有key获取系统参数
  • 实现类3
  • CompositeConfig(组合配置)
  • 实现了get(String key)方法,遍历每一个configList,查询config,如果能找到值,返回,否则,返回null
  • 实现了addListener(key, ConfigListener),给configList添加监听器
  • 实现了removeListener(ConfigListener)方法, 给configList移除监听器
  • 实现了removeListener(key, ConfigListener)方法, 给configList移除监听器
  • 实现类4
  • SystemConfig (系统配置)
  • 实现了get(key)方法,获取系统的值
  • 读取配置的顺序
  • apollo配置
  • 在resources资源文件夹下的META-INF/afterimage/ConfigProvider.def中配置, 格式如:order,name,providerClass,选择时,order小的优先,可以以#开头在上一行添加注释

100,ApolloConfig,cn.gov.zcy.afterimage.config.apollo.ApolloConfigProvider

  • Apollo环境可引入afterimage-config-apollo来支持apollo的配置读取、以及动态配置监听
<dependency>
    <groupId>cn.gov.zcy</groupId>
    <artifactId>afterimage-config-apollo</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

  • Spring配置
  • 在resources资源文件夹下的META-INF/afterimage/ConfigProvider.def中配置

0,SpringConfig,cn.gov.zcy.afterimage.config.spring.SpringConfigProvider

  • 系统配置
  • 在resources资源文件夹下的META-INF/afterimage/ConfigProvider.def中配置

1000,SystemConfig,cn.gov.zcy.afterimage.core.config.SystemConfigProvider

  • 默认配置为spring优先、apollo次之、System.getProperty最低
  • 配置的读取将按照spi的order配置,顺序从小到大读取,取到第一个不为null则返回
  • 也可以再启动时,设置-Dafterimage.config.order=SpringConfig,ApolloConfig 指定顺序,未指定的配置扩展将按默认顺序对应追加在后面
  • ObjectProvider 接口
  • 提供的方法:get()
  • 实现类
  • 实现类1、ApolloConfigProvider
  • NameSpace:afterimage.apollo.namespace
  • 实现了get()方法 --》从系统参数中获取名称空间,如果名称空间非空,获取apollo中当前名称空间的配置,否则:获取apollo “application”名称空间的配置项
  • 实现类2:SpringConfigProvider
  • 实现了get()方法 --》从SpringConfig获取实例
  • 实现类3:SystemConfigProvider
  • 实现了get()方法 --》获取SystemConfig实例
  • 实现类4:NopAlbumProvider
  • 实现了get()方法 --》获取NopAlbum实例
  • 实现类5:SoftReferenceAlbumProvider
  • 实现了get()方法 --》获取软引用类型ReferenceAlbum实例
  • 实现类6:StrongReferenceAlbumProvider
  • 实现了get()方法 --》获取强引用类型ReferenceAlbum实例
  • 实现类7:WeakReferenceAlbumProvider
  • 实现了get()方法 --》获取虚引用类型ReferenceAlbum实例
  • 2、afterimage-album 扩展调用结果的存储
  • 作用:存储dubbo接口调用结果
  • 定义的方法
  • init() 初始化,
  • destory() 销毁,
  • write(contextId,key,value,超期时间)存入数据,获取残影系统上下文数据,如果值为空,返回;如果上下文为空,抛错,获取上下文中的超期时间,如果这个时间为空,取入参中传递过来的超期时间,写入;
  • dowrite(contextId,key,value,超期时间)方法, 为null或小于1,将不过期
  • read(ContextId contextId, String key) 读取
  • clear(ContextId contextId, String key) 清理
  • clear(ContextId contextId) 清空整个context
  • 实现类
  • 实现类1:抽象类 AbstractAlbum
  • 实现了dowrite(contextId,key,value,超期时间)方法,获取-当不存在时,创建新的上下文,组装ValueWrapper(value,超期时间,系统时间)
  • 实现了read(ContextId contextId, String key),获取上下文,如果为空,return,否则 --》获取valueWrapper ,如果没有超期(时间为空或者小于1ms)–》返回valueWrapper中值 --》如果有配置超期时间,获取当前时间,减去valueWrapper中的系统时间,比较valueWrapper中的超期时间,如果大于 --》移除上下文,否则返回valueWrapper中的值
  • 实现了clear(ContextId contextId, String key), 获取上下文,移除对应的key
  • 提供了两抽象类
  • 1、getOrCreate(contextId) 获取或创建上下文
  • 2、get(ContextId contextId) 获取上下文
  • 实现类:ReferenceAlbum
  • Map类型 字段album,使用了ValueReference(有三个实现类,后面讲解)
  • 字段strength,枚举类型(STRONG强引用 SOFT软引用 -在内存不足时回收,每MB空余可保留1s,WEAK弱引用-GC就被回收 )
  • 提供了一个抽象方法referenceValue
  • 实现了三个静态内部类
  • StrongValueReference实现ValueReference接口,实现了get方法
  • SoftValueReference继承了SoftReference 实现了ValueReference
  • WeakValueReference继承了WeakReference 实现了ValueReference
  • 实现了方法init()
  • 实现了方法destory() 调用 album的清理
  • 实现了方法clear() 调用 album的remove
  • 实现了父类的抽象方法getOrCreate(contextId) 由context获取album Map的value,如果为空,说明需要初始化,给album初始化一个空的map,否则,返回map
  • 实现了父类的抽象方法get(contextId) 由context获取album Map的value,如果为空,返回空,否则,返回map
  • 实现类2:NopAlbum
  • 实现了这几个方法,都是空实现
  • init()方法初始化
  • destory() 销毁
  • doWrite(ContextId contextId, String key, Object value, Integer expireTimeMills) 存入
  • read(ContextId contextId, String key) 返回null
  • clear(ContextId contextId, String key) 清除第一个
  • clear(ContextId contextId) 清空
  • 实现类3:ReferenceAlbum 使用了引用实现,方便帮助GC 见上文
  • Album配置
  • 在resources资源文件夹下的META-INF/afterimage/AlbumProvider.def中配置,格式如:order,name,providerClass,选择时,order小的优先,可以以#开头在上一行添加注释
0,SoftReferenceAlbum,cn.gov.zcy.afterimage.core.album.reference.SoftReferenceAlbumProvider
100,WeakReferenceAlbum,cn.gov.zcy.afterimage.core.album.reference.WeakReferenceAlbumProvider
1000,StrongReferenceAlbum,cn.gov.zcy.afterimage.core.album.reference.StrongReferenceAlbumProvider
10000,NopAlbum,cn.gov.zcy.afterimage.core.album.NopAlbumProvider
  • 默认实现:
  • 0,SoftReferenceAlbum,cn.gov.zcy.afterimage.core.album.reference.SoftReferenceAlbumProvider
  • 软引用map实现,help gc
  • 100,WeakReferenceAlbum,cn.gov.zcy.afterimage.core.album.reference.WeakReferenceAlbumProvider
  • 弱引用map实现,help gc
  • 1000,DefaultAlbum,cn.gov.zcy.afterimage.core.album.reference.StrongReferenceAlbumProvider
  • map实现
  • 10000,NopAlbum,cn.gov.zcy.afterimage.core.album.NopAlbumProvider
  • 空实现
  • 只能使用一个具体实现,默认取order最小的那一个
  • 3、afterimage-captor 用来按需捕获调用结果进行存储
  • 背景知识:dubbo SPI 见上文dubbo filter的使用
  • 配置项为:afterimage.captor.dubbo.config
  • 配置格式:接口名1#方法名1=过期时间毫秒&方法名2=过期时间毫秒,接口名2#方法名1=过期时间&方法名2=过期时间
  • 可用*匹配所有方法名;过期时间单位为毫秒,当未配置或者小于1时,代表不过期,特别注意:当被优化方法执行完毕时,执行期间存储的调用将自动失效。
  • 配置eg: com.A#a=1&b&c=2,com.B#*=1
  • 目前不支持重载方法不同配置
  • AfterimageCaptorFilter实现了dubbo filter,使用代理设计模式,在调用dubbo接口前,先查询album是否有返回结果,在dubbo接口调用之后,将调用id和rpc结果放入到album中
  • 执行时机:消费方
  • **执行过程简述:**先获取dubbo配置,查询db(album)中是否存在该dubbo接口执行结果,有结果,直接返回该数据,否则,执行远程rpc调用,然后将方法入参和调用结果缓存到db(album)中
  • 类似于查询redis,查不到就查询db,并将结果放到redis中
  • 添加Activate注解,标识其为被代理对象,其注解含义如下
  • group :所属组:消费者,只能在消费端使用
  • order: 多个filter的执行顺序(越小越早)
  • 文件名:com.alibaba.dubbo.rpc.Filter 对于Filter的接口
  • 执行过程详述:在resources目录下新建META-INF文件夹,然后建立子文件夹dubbo,最后新建文件com.alibaba.dubbo.rpc.Filter --》key为过滤器的实例名,value为过滤器的全类名 --》在dubbo接口执行之前,会进入拦截器里面 --》
  • 在拦截器里面 --》先获取CompositeConfig配置,如果配置项不存在或者开关未开启,提前return --》否则,获取配置项,优先上下文配置,获取dubbo接口全路径,不存在的话,获取Config中的数据 --》读取配置项,入参为原始配置 + dubbo执行信息,在工具类里面获取dubboConfig --》获取超期时间 --》如果获取的配置为空,执行invoke方法调用远程rpc,否则获取上下文,然后生成调用id --》获取应用程序信息,group信息,版本信息,接口名和方法名,入参类型信息(用逗号链接),入参信息(用逗号链接) --》使用 + 将上述全部信息连接后返回 --》获取db数据(album),由上下文+dubbo信息查询album中是否存在数据,如果为空,返回null,否则 --》判断是否有设置超期时间,如果没有设置,返回album对应的值,–》如果已经超期了,从album中删除数据,否则,返回album对应的值 --》有值,说明近期有调用,AsyncRpcResult返回该值,否则,没有结果
  • 执行rpc调用,拿到返回结果,如果返回结果没有异常,将结果写入到album中,入参为上下文id,dubbo组装参数后的id,rpc调用的结果,超期时间 --》album如果没有key,初始化,然后以dubbo组装参数后的id为key,rpc结果,超期时间,当前时间这三个字段组装的对象为value,存入map中
  • 如果这个过程中发生了异常,分类讨论,如果执行了远程rpc,并且结果非空,返回执行结果,结果为空,抛出异常 --》没有执行远程rpc,此时调用远程rpc接口,并返回
  • Action:这个兜底逻辑中,执行远程rpc后,没有把执行结构放入到album中
  • 4、afterimage-boot 启动afterimage
  • 实现了切面逻辑 ,源码分析如下
  • 注入切面的逻辑
  • 5、afterimage-core 核心类,
  • 定义了spi拓展接口:
  • cn.gov.zcy.afterimage.core.config.Config:可用于配置读取、监听的扩展
  • cn.gov.zcy.afterimage.core.album.Album:用于存储调用结果
  • 6、afterimage-boot-dubbo模块
  • AfterimageBootFilter实现了dubbo filter,使用代理设计模式,在调用dubbo接口前,先查询album是否有返回结果,在dubbo接口调用之后,将调用id和rpc结果放入到album中
  • 执行时机:生产方
  • 执行过程简述:先获取dubbo配置,查询Config中配置是否开启,没开启,执行远程rpc,否则,查询配置项,有方法入参查询超期时间,配置超期时间,执行rpc调用,最后清理db(album) 数据
  • 可以类似于redis中:缓存时间到期了,清理redis缓存
  • Action:这个操作不优雅,它是在每次调用dubbo接口时,判断当前执行的方法有没有过期,可以模仿redis删除key的实现思路
  • 添加Activate注解,标识其为被代理对象,其注解含义如下
  • group :所属组:提供者,只能在服务提供端使用
  • 前提:需要引入对应captor才会优化相应的调用
  • 配置项为:afterimage.boot.dubbo.config
  • 配置格式:接口名1#方法名1=过期时间毫秒&方法名2=过期时间毫秒,接口名2#方法名1&方法名2=过期时间
  • 可用 * 匹配所有方法名;过期时间单位为毫秒,当未配置或者小于1时,代表不过期,特别注意:当被优化方法执行完毕时,执行期间存储的调用将自动失效。
  • 配置eg: com.A#a=1&b&c=2,com.B#*=1
  • 目前不支持重载方法不同配置
  • 在resources目录下新建META-INF文件夹,然后建立子文件夹dubbo,最后新建文件com.alibaba.dubbo.rpc.Filter --》key为过滤器的实例名,value为过滤器的全类名
  • 在服务提供端接口返回之前,会进入拦截器里面 --》首先获取CompositeConfig配置,如果配置项不存在或者开关未开启,执行dubbo接口invoke业务逻辑 --》否则,获取配置项详情,原始配置 格式如:接口名#方法名=过期时间&方法名=过期时间,接口名#方法名=过期时间&方法名=过期时间 --》获取配置详情,如果为空,跳过,否则 --》去除全部空格,接口的配置用’,'隔开,接口名和方法使用“#”分割,如果不合规范,跳过 --》如果当前的接口名与入参接口名相符,继续匹配方法的参数,使用“&”分割,然后使用 “=” 分割入参的key和value,如果key value不是一个pair,跳过,否则,获取入参的key --》如果key为通配符“*” 或者符合入参方法名,执行DubboConfig方法 --》设置超期时间,目前只有expireMills一个配置项,返回DubboConfig —》如果获取到的DubboConfig对象为null,执行dubbo业务逻辑并返回,否则 --》调用startAfterimageManage,底层为AfterimageManage的start1方法,入参为超期时间 --》然后执行dubbo invoke执行业务方法 --》最后,调用AfterimageManage的end方法清理数据
  • Action:这个过滤器如果执行报错,不需要补偿吗?
  • 残影系统使用的设计模式:
  • 1、代理模式 在dubbo invoke之前和之后执行某些操作
  • 2、filter模式:拦截器设计模式
  • 源码分析:
  • 入口:切面AfterimageAspectj
  • 在构造器里面初始化,如果已经初始化,提前return,否则,调用AfterimageManage初始化数据 --》对ConfigLoader进行初始化 --》对AlbumLoader进行初始化 --》环切操作,先判断ConfigLoader中“afterimage.spring.enabled”配置项是否打开,如果没有打开,直接执行业务逻辑,否则 --》调用start0开始执行切面逻辑,然后执行业务逻辑,最后执行残影的清理操作(end方法)
  • AfterimageManage --》初始化init,如果已经初始化,return,否则 --》初始化项目,
  • ConfigLoader
  • order_key:afterimage.config.order
  • PATH = “META-INF/afterimage/ConfigProvider.def” 使用系统配置
  • order:1000
  • name:SystemConfig
  • providerClassName:cn.gov.zcy.afterimage.core.config.SystemConfigProvider
  • CompositeConfig CONFIG
  • 初始化,如果CONFIG非空,说明已经被初始化了,提前return --》 由固定的PATH查询Spi order_key拓展信息 --》加载资源,由path获取类加载器中的urls,–》如果加载出的资源为空,return,否则 --》解析路径,如果路径长度不等于3,抛出异常,否则 --》定义SpiModel,并组装顺序、名称、类名 --》按顺序排序 --》定义组合配置CompositeConfig,将SpiModel转换为CompositeConfig --》按key为name,value为spiModel构建为map --》指定顺序排序(afterimage–config–order) --》循环遍历SpiModel,通过类名获取类实例,然后添加到配置中
  • AlbumLoader
  • ALBUM_KEY = “afterimage.album”
  • PATH = “META-INF/afterimage/AlbumProvider.def”
  • ALBUM
  • List < SpiModel> SPI_MODELS
  • order :0
  • name:SoftReferenceAlbum
  • providerClassName:cn.gov.zcy.afterimage.core.album.reference.SoftReferenceAlbumProvider
  • 初始化 --》如果CONFIG非空,说明已经被初始化了,提前return --》 由固定的PATH查询Spi拓展信息 --》加载资源,由path获取类加载器中的urls,–》如果加载出的资源为空,return,否则 --》解析路径,如果路径长度不等于3,抛出异常,否则 --》定义SpiModel,并组装顺序、名称、类名 --》按顺序排序 --》按key为name,value为spiModel构建为map --》指定顺序排序(afterimage–config–order) --》循环遍历SpiModel,通过类名获取类实例,然后添加到配置中
  • 加载:–》获取SPI_MODELS的第一条数据, --》如果指定了CompositeConfig,使用指定的,否则 --》调用ConfigLoader初始化接口,返回CONFIG --》从配置项中读取“afterimage.album”,使用指定的spiModel --》获取单签拓展点实例信息 --》添加钩子函数,在程序结束时自动销毁album
  • 强制清除方法 forceClear --》获取残影上下文,如果为空,提前return,否则 --》由AlbumLoader获取ALBUM,做清理工作 --》然后由残影上下文中移除ThreadLocal数据
  • start0
  • 执行时机
  • 当进入切面后
  • 业务逻辑:
  • 当某线程连续调用start时,只有第一次的配置生效 --》入参为残影注解,如果没有配置过期时间,返回null --》入参中的captor非空,循环遍历captorConfig --》组装captor(目前仅为dubbo接口),config(dubbo接口的全路径)–》组装到配置项AfterimageConfig中 --》然后调用start(afterimageConfig)方法执行后续逻辑 --》
  • 当嵌套多次start时,计数器会加1,调用end是减1,当为0时,代表上下文安全结束 --》判断是否是新的上下文,如果通过Local能获取上下文,返回该数据,否则 --》 创建一个空的上下文到Local中,返回Local --》计数器自增,如果计数器值不为1,返回false,否则,将入参中的配置放入上下文中,然后返回true
  • start1
  • 执行时机
  • 对于每一个执行的dubbo,都会进入拦截器里面去,然后判断有没有匹配上,有配置上,重新计算超期时间
  • 业务逻辑
  • 当某线程连续调用start时,只有第一次的配置生效 --》过期时间毫秒-为null或小于1,将不过期 --》获取Local里面的上下文,如果数据非空,返回上下文,否则 --》初始化Local后返回 --》计数器自增,如果计数器不为1,返回false,否则,组装配置后,返回true
  • Action:计数器起的作用是啥? 返回的true,false是啥意思?
  • 计数器是为空防止一次请求中,进入切面里面多次
  • Action:提供的两filter方法会拦截全部的dubbo接口,这样做不会影响性能吗?
  • start(expireMills, captorConfigList) 当某线程连续调用start时,只有第一次的配置生效
  • end 在结束后必须调用end --》获取Local中的上下文,如果上下文为空,抛错异常,否则 --》计数器自减 --》如果数量不为0,返回false,标识在其它上下文之中,不用清理数据,否则 --》返回true,获取Album,做清理操作,清理上下文信息,return
  • SystemConfigProvider 系统配置提供方
  • SoftReferenceAlbumProvider

3、SPI总结

1、利用Dubbo SPI机制提供的良好拓展性

  • 1、整个框架中针对不同的场景,恰到好处地使用了各种设计模式
  • 2、基于Dubbo SPI 加载机制,让整个框架的接口和具体实现完全解耦合

2、缓存思想的运用

  • 先获取dubbo配置,查询db(album)中是否存在该dubbo接口执行结果,有结果,直接返回该数据,否则,执行远程rpc调用,然后将方法入参和调用结果缓存到db(album)中
  • 先获取dubbo配置,查询Config中配置是否开启,没开启,执行远程rpc,否则,查询配置项,有方法入参查询超期时间,配置超期时间,执行rpc调用,最后清理db(album) 数据
相关文章
|
7月前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
194 4
|
7月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
7月前
|
负载均衡 JavaScript 前端开发
分片上传技术全解析:原理、优势与应用(含简单实现源码)
分片上传通过将大文件分割成多个小的片段或块,然后并行或顺序地上传这些片段,从而提高上传效率和可靠性,特别适用于大文件的上传场景,尤其是在网络环境不佳时,分片上传能有效提高上传体验。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
11月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
279 2
|
7月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
677 29
|
7月前
|
移动开发 前端开发 JavaScript
从入门到精通:H5游戏源码开发技术全解析与未来趋势洞察
H5游戏凭借其跨平台、易传播和开发成本低的优势,近年来发展迅猛。接下来,让我们深入了解 H5 游戏源码开发的技术教程以及未来的发展趋势。
|
7月前
|
存储 前端开发 JavaScript
在线教育网课系统源码开发指南:功能设计与技术实现深度解析
在线教育网课系统是近年来发展迅猛的教育形式的核心载体,具备用户管理、课程管理、教学互动、学习评估等功能。本文从功能和技术两方面解析其源码开发,涵盖前端(HTML5、CSS3、JavaScript等)、后端(Java、Python等)、流媒体及云计算技术,并强调安全性、稳定性和用户体验的重要性。
|
10月前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
10月前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
10月前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析

推荐镜像

更多
  • DNS