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

dubbo SPI插件扩展点使用

参考:SPI插件扩展点

Dubbo SPI概述

使用IoC容器帮助管理组件的生命周期、依赖关系注入等是很多开发框架的常用设计,Dubbo中内置了一个轻量版本的IoC容器,用来管理框架内部的插件,实现包括插件实例化、生命周期、依赖关系自动注入等能力。

Dubbo插件体系与IoC容器具有以下特点:

  • 核心组件均被定义为插件,用户或二次开发者扩展非常简单。在无需改造框架内核的情况下,用户可以基于自身需求扩展如负载均衡、注册中心、通讯协议、路由等策略。
  • 平等对待第三方扩展实现。Dubbo中所有内部实现和第三方实现都是平等的,用户可以基于自身业务需求替换Dubbo提供的原生实现。
  • 插件依赖支持自动注入(IoC)。如果插件实现依赖其他插件属性,则Dubbo框架会完成该依赖对象的自动注入,支持属性、构造函数等方式。
  • 插件扩展实现支持AOP能力。框架可以自动发现扩展类的包装类,通过包装器模式对插件进行Aop增强。
  • 支持插件自动激活。通过为插件实现指定激活条件(通过注解参数等),框架可在运行时自动根据当前上下文决策是否激活该插件实现。
  • 支持插件扩展排序。

Dubbo SPI插件及详情

声明周期与事件回调

SPI扩展定义功能说明实例实现激活条件
org.apache.dubbo.common.lang.ShutdownHookCallback优雅下线回调逻辑扩展点,Dubbo进程销毁前会调用所有ShutdownHookCallback实现无需配置,自动激活
org.apache.dubbo.common.threadpool.event.ThreadPoolExhaustedListener当dubbo业务线程池满时,会调用这个扩展点发出事件通知org.apache.dubbo.metrics.collector.sample.MetricThreadPoolExhaustedListener通过dubbo.protocol.threadpool-exhausted-listeners=spi-name1,spi-name2设置激活哪些实现
org.apache.dubbo.rpc.ExporterListener每个Exporter成功export/unexport发布后,都会回调这个扩展点org.apache.dubbo.rpc.listener.InjvmExporterListener扩展实现必须增加@Activate注解激活,可按需配置激活条件。支持通过在URL中配置export.listener=spi-name1,spi-name2控制具体哪个实现
org.apache.dubbo.rpc.InvokerListener每个Invoker成功refer/destory发布后,都会回调这个扩展点org.apache.dubbo.rpc.listener.DeprecatedInvokerListener扩展实现必须增加@Activate注解激活。可按需配置激活条件。支持通过在URL中配置invoker.listener=pi-name1,spi-name2控制具体哪个实现
org.apache.dubbo.common.status.StatusChecker对外透出内部组件状态的扩展点,每个需要透出状态的组件均可实现次扩展点org.apache.dubbo.rpc.protocol.dubbo.status.ThreadPoolStatusChecker通过设置dubbo.protocol.status=spi-name1,spi-name2激活
org.apache.dubbo.config.ServiceListenerServiceConfig回调扩展点,每个ServiceConfig成功export/unexport后都会被回调。拦截点与ExporterListener略有不同无需配置,自动激活
org.apache.dubbo.registry.RegistryServiceListener服务URL向注册中心register/unregister之后的回调扩展点,所有扩展实现会被依次通知扩展实现必须增加@Activate注解激活,默认激活。支持通过在Registry URL中配置registry.listeners控制具体激活哪个实现,如dubbo.registry.parameters.registry.listeners=spi-name1,spi-name2
org.apache.dubbo.registry.integration.RegistryProtocolListener用于接口级服务发现org.apache.dubbo.registry.client.migration.MigrationRuleListeneregistryProtocol listener is introduced to provide a chance to user to customize or change export and refer behavior of RegistryProtocol. For example: re-export or re-refer on the fly when certain condition meets.
org.apache.dubbo.qos.probe.LivenessProbe生命周期检测扩展点。可通过qos live http接口配置为k8s liveness检测,qos live会检测所有LivenessProbe扩展点实现扩展实现必须增加@Activate注解激活,默认激活。支持通过在URL中配置dubbo.application.liveness-probe=spi-name2,spi-name2控制具体激活哪些实现
org.apache.dubbo.qos.probe.ReadinessProbe生命周期检测扩展点。可通过qos read http接口配置为k8s readiness检测,qos read会检查所有ReadinessProbe扩展点实现扩展实现必须增加@Activate注解激活,默认激活。支持通过在URL中配置dubbo.application.readiness-probe=spi-name2,spi-name2控制具体激活哪些实现
org.apache.dubbo.qos.probe.StartupProbe生命周期检测扩展点。可通过qos startup http接口配置为k8s startup,qos startup会检查所有StartupProbe扩展点实现扩展实现必须增加@Activate注解激活,默认激活。支持通过在URL中配置dubbo.application.startup-probe=spi-name2,spi-name2控制具体激活哪些实现
org.apache.dubbo.common.deploy.ApplicationDeployListenerDubbo进程启动生命周期中的回调扩展,支持包括初始化、启动成功、停止等多个回调点。如果是多应用部署的场景,则是单应用粒度的生命周期回调org.apache.dubbo.security.cert.CertDeployerListener无需配置,自动激活
org.apache.dubbo.common.deploy.ModuleDeployListenerDubbo进程启动生命周期中的回调扩展,支持包括初始化、启动成功、停止等多个回调点。如果是多模块部署的场景,则是单模块粒度的生命周期回调无需配置,自动激活
org.apache.dubbo.qos.api.BaseCommandQoS命令扩展点,实现扩展点增加新QoS命令org.apache.dubbo.qos.command.impl.Ls无需配置,自动激活

配置相关

SPI扩展定义功能说明实例实现激活条件
org.apache.dubbo.common.extension.ExtensionInjectorIoC注入器扩展点,通过扩展可以实现多种类型的治理自动注入,用于Dubbo框架SPI实例与不同IOC容器之间的结合,如支持Spring Bean注入SPI实例org.apache.dubbo.config.spring.extension.SpringExtensionInjector无需额外配置,自动激活
org.apache.dubbo.common.infra.InfraAdapter用于自定义加载环境变量的扩展实现,可以批量的通过编码的方式获取想要读取的环境变量,框架会自动将这些值附加到每个服务的URL参数中org.apache.dubbo.common.infra.support.EnvironmentAdapter无需额外配置,自动激活
org.apache.dubbo.common.logger.LoggerAdapter日志框架适配,如果要额外提供Dubbo不支持的日志框架适配,可以使用此扩展点org.apache.dubbo.common.logger.slf4j.Slf4jLoggerAdapter通过dubbo.application.logger=spi-name激活
org.apache.dubbo.config.ConfigInitializer在配置初始化之前,服务初始化之前定制ServiceConfig、ReferenceConfig参数扩展实现必须增加@Active注解激活,可按需增加激活条件
org.apache.dubbo.config.ConfigPostProcessor在配置初始化之后,服务初始化之前定制ServiceConfig、ReferenceConfig参数,在ConfigInitializer之后执行扩展实现必须增加@Active注解激活,可按需增加激活条件
org.apache.dubbo.config.spring.context.DubboSpringInitCustomizer无需额外配置,自动激活

服务发现


SPI扩展定义
功能说明实例实现激活条件
org.apache.dubbo.registry.AddressListener用于服务发现。URL地址通知发生时会调用此扩展点实现,可做一些地址预处理操作扩展实现修增加@Activate注解激活,可按需配置激活条件
org.apache.dubbo.registry.ProviderFirstParams用于服务发现。用于制定URL参数的优先级,改扩展点实现返回的参数列表(provider优先级高于consumer),多个扩展实现的参数列表会合并org.apache.dubbo.registry.support.DefaultProviderFirstParams无需配置,自动激活
org.apache.dubbo.registry.RegistryFactory用于接口级服务发现。通过扩展此SPI可实现不同注册中心适配org.apache.dubbo.registry.nacos.NacosRegistryFactory通过配置dubbo.registry.address=spi-name://ip:port激活
org.apache.dubbo.registry.client.RegistryClusterIdentifier用于应用级服务发现。dubbo框架支持为注册中心集群指定标识,通过此标识key可以对地址URL进行分类,从而根据不同集群做一些事情。此扩展点给用户机会指定那个key来作为注册中心集群分类org.apache.dubbo.registry.client.DefaultRegistryClusterIdentifier通过dubbo.provider.parameters.registry-cluster-tyoe=spi-name激活指定扩展实现
org.apache.dubbo.registry.client.ServiceDiscoveryFactory用于应用级服务发现。通过扩展此SPI实现不同注册中心适配org.apache.dubbo.registry.nacos.NacosServiceDiscoveryFactory通过配置dubbo.registry.address=spi-name://ip:port指定 ,同时指定dubbo.registry.register-mode=instance激活应用服务发现
org.apache.dubbo.registry.client.ServiceInstanceCustomizer用于应用级服务发现。在应用级地址实例URL注册到注册中心之前,通过此扩展点实现进行定制org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataCustomizer无需配置,自动激活
org.apache.dubbo.registry.client.migration.MigrationAddressComparator用于应用级服务发现。作为接口级地址向应用级地址迁移机制的一部分,在框架决策是否迁移之前,用于对两边的地址做比较,可自行定制决策逻辑org.apache.dubbo.registry.client.migration.DefaultMigrationAddressComparator无需配置,自动激活
org.apache.dubbo.metadata.MetadataParamsFilter用于应用级服务发现。通过该扩展点可以控制那些参数注册到注册中心,那些参数注册到服务元数据org.apache.dubbo.metadata.DefaultMetadataParamsFilter扩展实现必须增加@Active注解激活。支持通过在URL中配置params-filter控制具体激活哪个实现,如 dubbo.provider.parameters.params-filter=-default,spi-name1 表示关闭所有扩展实现仅启用 spi-name1 实现
org.apache.dubbo.registry.client.metadata.ServiceInstanceNotificationCustomizer用于应用级服务发现。识别特定类型的地址URL,实例扩展实现用于识别Spring Cloud Alibaba Dubbo地址类型org.apache.dubbo.registry.client.metadata.SpringCloudServiceInstanceNotificationCustomizer无需配置,自动激活
org.apache.dubbo.registry.integration.ServiceURLCustomizer用于接口级服务发现。在优化接口级地址列表并做URL精简时,可以通过该扩展点指定那些URL注册到注册中心、那些URL不注册。当有多个扩展实现时,效果叠加org.apache.dubbo.registry.integration.DefaultServiceURLCustomizer无需配置,自动激活
org.apache.dubbo.rpc.cluster.ProviderURLMergeProcessor用于接口级服务发现。该扩展点用于完成consumer url和provider url合并,可以使用不同的实现控制合并策略,以确保保留不同的key,使用不同的覆盖关系(仅对接口级服务发现有效)org.apache.dubbo.rpc.cluster.support.merger.DefaultProviderURLMergeProcessor可通过dubbo.consumer.url-merge-processor=spi-name启用指定扩展实现

RPC与流量管控

SPI扩展定义功能说明实例实现激活条件
org.apache.dubbo.rpc.ProtocolRPC协议实现扩展点。通过扩展该扩展点增加更多的协议实现org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol通过配置dubbo.protocol.name=spi-name激活
org.apache.dubbo.rpc.ProxyFactoryRPC代理实现的扩展点。可以提供多种不同的代理实现,如字节码增加、JDK等org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory通过配置dubbo.application.compiler=spi-name激活
org.apache.dubbo.rpc.ZoneDetector在多注册中心场景下,Dubbo提供了自动同区域有限的匹配策略。此扩展点可以让用户更方便的扩展zone读取策略,以更灵活的决策当前请求属于哪个zone。默认情况下框架会从RpcContext特点的Key读取只会有一个ZoneDetector实现会被激活。key为default的扩展实现被激活
org.apache.dubbo.rpc.cluster.ClusterRpc请求容灾策略扩展点。比如设置请求失败时的动作,如FailoverCluster、FailfastCluster等org.apache.dubbo.rpc.cluster.support.FailoverCluster通过配置dubbo.consumer.cluster=spi-name激活
org.apache.dubbo.rpc.cluster.LoadBalance负载均衡策略扩展点,通过扩展可以实现不同的负载均衡策略org.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance通过配置dubbo.consumer.loadbalance=spi-name激活
org.apache.dubbo.rpc.HeaderFilter在rpc请求前,通过不同的扩展实现各种attachment/header校验策略org.apache.dubbo.rpc.filter.TokenHeaderFilter扩展实现必须通过@Activate注解激活。支持通过在URL中配置header.filter=spi-name1,spi-name2控制具体激活哪个实现
org.apache.dubbo.rpc.FilterRPC请求过滤器,用于在请求发起前、相应结果返回后,对RPC调用进行过滤org.apache.dubbo.rpc.filter.GenericFilter扩展实现必须增加 @Activate 注解激活,可按需配置激活条件如@Activate(group=“consumer”)。支持通过在 URL 中配置 service.filter=spi-name1,spi-name2 控制具体在provider侧激活哪些实现;支持通过在 URL 中配置 reference.filter=spi-name1,spi-name2 控制具体在consumer侧激活哪些实现
org.apache.dubbo.rpc.cluster.filter.ClusterFilterRPC请求过滤器,与Filter作用相同,但ClusterFilter发生在选址之前,对于大部分用户可直接使用org.apache.dubbo.rpc.Filterorg.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter扩展实现必须增加 @Activate 注解激活,可按需配置激活条件。支持通过在 URL 中配置 filter=spi-name1,spi-name2 控制具体激活哪个实现
org.apache.dubbo.rpc.cluster.RouterFactory路由器扩展点,可以通过扩展增加不同的路由规则策略扩展实现必须增加 @Activate 注解激活,可按需配置激活条件。支持通过在 URL 中配置 router=spi-name1,spi-name2 控制具体激活哪个实现
org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory与RouterFactory相同作用,但具备更高性能。对大部分用户,简单起见使用RouterFactoryorg.apache.dubbo.rpc.cluster.router.condition.ConditionStateRouterFactory扩展实现必须增加 @Activate 注解激活,可按需配置激活条件。支持通过在 URL 中配置 router=spi-name1,spi-name2 控制具体激活哪个实现
org.apache.dubbo.rpc.cluster.ConfiguratorFactory动态配置规则扩展点,通过增加扩展可以增加不同的动态配置规则策略org.apache.dubbo.rpc.cluster.configurator.override.OverrideConfiguratorFactory扩展实现必须增加 @Activate 注解激活,可按需配置激活条件。支持通过在 URL 中配置 router=spi-name1,spi-name2 控制具体激活哪个实现
org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.ValuePattern路由规则处理扩展点。条件路由规则内部的规则处理器,通过扩展可支持更丰富的规则和匹配条件org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.range.RangeValuePattern自动激活,通过规则控制激活哪个具体实现
org.apache.dubbo.rpc.cluster.router.condition.matcher.ConditionMatcherFactory路由规则处理扩展点。条件路由规则内部的规则处理器,通过扩展可支持更丰富的规则和匹配条件org.apache.dubbo.rpc.cluster.router.condition.matcher.argument.ArgumentConditionMatcherFactory扩展实现必须增加 @Activate 注解激活,可按需配置激活条件。
org.apache.dubbo.rpc.cluster.router.mesh.util.TracingContextProviderMashRule路由规则处理扩展点,可用于从不同的第三方Tracing系统读取上下文无需配置,自动激活
org.apache.dubbo.rpc.cluster.router.mesh.route.MeshEnvListenerFactoryMashRule路由规则处理扩展点无需配置,自动激活
org.apache.dubbo.cache.CacheFactory缓存实现扩展点,用于缓存RPC调用结果org.apache.dubbo.cache.support.expiring.ExpiringCacheFactory通过在 URL 中配置 cache=spi-name 控制具体激活哪个实现
org.apache.dubbo.common.serialize.Serialization序列化协议扩展点,如果要扩展新的序列化协议,可以使用此扩展点org.apache.dubbo.common.serialize.hessian2.Hessian2Serialization通过配置 dubbo.provider.serialization=spi-name 激活
org.apache.dubbo.common.threadpool.ThreadPool线程池策略扩展点。目前仅适用于dubbo协议实现,不适用于triple协议org.apache.dubbo.common.threadpool.support.fixed.FixedThreadPool通过配置 dubbo.provider.threadpool=spi-name 激活
org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory线程池隔离策略扩展点,如dubbo协议、triple协议都可以定义不同的隔离策略,每个协议可设置一个线程池隔离策略org.apache.dubbo.rpc.protocol.tri.transport.TripleIsolationExecutorSupportFactory跟随用户配置的 dubbo.protocol.name,因此必须确保配置的 key 值与 rpc 协议名相同
org.apache.dubbo.rpc.PenetrateAttachmentSelector通过此扩展点可以自定义参数全链路传递(dubbo链路),Dubbo 默认只会在 A->B 链路传递参数,通过此扩展点可以控制参数在 A->B->C一直传递下去。无需配置,自动激活

服务治理

SPI扩展定义功能说明实例实现激活条件
org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory配置中心核心扩展点。用于提供不同配置中心适配实现org.apache.dubbo.configcenter.support.nacos.NacosDynamicConfigurationFactory通过指定dubbo.config-center.address=spi-name://激活
org.apache.dubbo.metadata.report.MetadataReportFactory元数据中心扩展点,用于提供新的元数据中心存储实现org.apache.dubbo.metadata.store.nacos.NacosMetadataReportFactory通过指定dubbo.metadata-report.address=spi-name://激活
org.apache.dubbo.metrics.report.MetricsReporterFactoryMetrics指标上报扩展点,可以通过扩展点实现适配到不同的Metrics后端服务org.apache.dubbo.metrics.prometheus.PrometheusMetricsReporterFactory通过指定 dubbo.metrics.protocol=spi-name 激活
org.apache.dubbo.metrics.collector.MetricsCollector框架内部Metrics采集扩展点,可以通过扩展支持RPC、注册中心等不同组件的metrics埋点数据采集org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector扩展实现必须增加 @Activate 注解激活,可按需增加激活条件
org.apache.dubbo.auth.spi.AccessKeyStorage采用dubbo-auth模块,该扩展点可不同的AK来源读取方法org.apache.dubbo.auth.DefaultAccessKeyStorage通过指定 accessKey.storage URL 参数激活
org.apache.dubbo.auth.spi.Authenticator用于dubbo-auth模块,该扩展点用于实现具体的认证逻辑org.apache.dubbo.auth.AccessKeyAuthenticator通过指定 authenticator URL 参数激活
org.apache.dubbo.common.ssl.CertProviderTLS证书来源扩展,用于适配不同的证书来源实现org.apache.dubbo.common.ssl.impl.SSLConfigCertProvider扩展实现必须增加 @Activate 注解激活

协议与传输层实现

SPI扩展定义功能说明实例实现激活条件
org.apache.dubbo.remoting.ChannelHandler
org.apache.dubbo.remoting.Codec
org.apache.dubbo.remoting.Codec2
org.apache.dubbo.remoting.Dispatcher
org.apache.dubbo.remoting.Transporter
org.apache.dubbo.rpc.protocol.dubbo.ByteAccessor
org.apache.dubbo.remoting.api.pu.PortUnificationTransporter
org.apache.dubbo.remoting.api.WireProtocol
org.apache.dubbo.remoting.api.connection.ConnectionManager
org.apache.dubbo.remoting.exchange.Exchanger
org.apache.dubbo.remoting.http.HttpBinder
org.apache.dubbo.remoting.http12.message.HttpMessageEncoderFactory
org.apache.dubbo.remoting.http12.message.HttpMessageDecoderFactory
org.apache.dubbo.remoting.http12.h2.Http2ServerTransportListenerFactory
org.apache.dubbo.remoting.http12.h1.Http1ServerTransportListenerFactory
org.apache.dubbo.remoting.http12.message.HttpMessageAdapterFactory
org.apache.dubbo.metadata.annotation.processing.builder.TypeBuilder
org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor
org.apache.dubbo.metadata.annotation.processing.rest.ServiceRestMetadataResolver
org.apache.dubbo.metadata.definition.builder.TypeBuilder
org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor
org.apache.dubbo.metadata.rest.ServiceRestMetadataReader
org.apache.dubbo.rpc.protocol.tri.compressor.Compressor
org.apache.dubbo.rpc.protocol.tri.compressor.DeCompressor
org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentConverter
org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentResolver
org.apache.dubbo.rpc.protocol.tri.rest.filter.RestExtension
org.apache.dubbo.rpc.protocol.tri.rest.filter.RestExtensionAdapter
org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMappingResolver
org.apache.dubbo.rpc.protocol.tri.route.RequestHandlerMapping
org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.provider.BaseProviderParamParser
org.apache.dubbo.metadata.rest.ServiceRestMetadataResolver
org.apache.dubbo.rpc.protocol.rest.filter.RestRequestFilter
org.apache.dubbo.rpc.protocol.rest.filter.RestResponseFilter
org.apache.dubbo.metadata.rest.NoAnnotatedParameterRequestTagProcessor
org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec
org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionPreBuildIntercept
org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.BaseConsumerParamParser
org.apache.dubbo.remoting.http.factory.RestClientFactory
org.apache.dubbo.rpc.protocol.rest.filter.RestResponseInterceptor
org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter

框架内部实现

SPI扩展定义功能说明实例实现激活条件
org.apache.dubbo.common.url.component.param.DynamicParamSource可通过扩展自定义动态参数列表,与 Dubbo3 中关于 URL 存储的优化相关。org.apache.dubbo.common.url.component.param.DefaultDynamicParamSource
org.apache.dubbo.common.compiler.Compiler用于设置 Dubbo IoC 容器的自适应扩展实现依赖的字节码工具。默认使用 javassist,可设置使用 jdk 或 bytebuddy 等实现。org.apache.dubbo.common.compiler.support.JavassistCompiler
org.apache.dubbo.common.serialize.MultipleSerialization
org.apache.dubbo.common.convert.Converter实现原类型到目标类型的转换,多限于框架内部集成使用org.apache.dubbo.common.convert.StringToFloatConverter
org.apache.dubbo.common.config.OrderedPropertiesProvider通过扩展可以为框架提供更多的 properties 来源,多限于框架内部集成使用
org.apache.dubbo.common.convert.multiple.MultiValueConverter实现原类型到目标类型的转换,多限于框架内部集成使用org.apache.dubbo.common.convert.multiple.StringToArrayConverter
org.apache.dubbo.common.store.DataStore
org.apache.dubbo.common.threadpool.manager.ExecutorRepository
org.apache.dubbo.spring.security.jackson.ObjectMapperCodecCustomer
org.apache.dubbo.validation.Validation
org.apache.dubbo.rpc.PathResolver
org.apache.dubbo.rpc.model.PackableMethodFactory
org.apache.dubbo.rpc.model.ApplicationInitListener
org.apache.dubbo.rpc.model.BuiltinServiceDetector
org.apache.dubbo.rpc.model.ScopeModelInitializer
org.apache.dubbo.aot.api.ReflectionTypeDescriberRegistrar
org.apache.dubbo.aot.api.ProxyDescriberRegistrar
org.apache.dubbo.common.json.JsonUtil
org.apache.dubbo.rpc.protocol.injvm.ParamDeepCopyUtil
org.apache.dubbo.aot.api.ResourceDescriberRegistrar
org.apache.dubbo.common.context.ApplicationExt
org.apache.dubbo.common.context.ModuleExt
org.apache.dubbo.metrics.service.MetricsService用于对外发布/透出 Metrics 指标的内部服务定义,以标准 Dubbo 服务形式发布。org.apache.dubbo.metrics.service.DefaultMetricsService
org.apache.dubbo.metrics.service.MetricsServiceExporter
org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder
org.apache.dubbo.rpc.cluster.filter.InvocationInterceptorBuilder
org.apache.dubbo.rpc.cluster.Merger目前用于多 group 调用场景,对请求结果进行合并
org.apache.dubbo.rpc.cluster.governance.GovernanceRuleRepository
org.apache.dubbo.qos.permission.PermissionChecker用于检查扩展QoS执行权限检查逻辑,配合每个 QoS 命令配置的 @CMD 权限注解,结合上下文进行检查。org.apache.dubbo.qos.permission.DefaultAnonymousAccessPermissionChecker默认只支持 qosPermissionChecker
org.apache.dubbo.common.status.reporter.FrameworkStatusReporter用于上报 Dubbo 框架内部运行状态的扩展点,目前框架在服务发现模型自动迁移等位置做了统计埋点,所有迁移动作都会通过此扩展实现上报出去。未来可考虑用 metrics标准埋点取代。
org.apache.dubbo.registry.client.metadata.MetadataServiceURLBuilder用于应用级服务发现。在收到应用级地址 URL 推送后,生成 MetadataService URL 时的定制逻辑(仅对点对点应用级地址发现有效)org.apache.dubbo.registry.client.metadata.StandardMetadataServiceURLBuilder
org.apache.dubbo.metadata.ServiceNameMapping用于应用级服务发现org.apache.dubbo.registry.client.metadata.MetadataServiceNameMapping

Dubbo SPI插件定义以及使用

协议扩展

扩展说明

RPC协议扩展,封装远程调用细节。

契约:

  • 当用户调用refer()所返回的Invoker对象的invoke()方法时,协议需相应执行同URL远端export()传入的Invoker对象的invoker()方法。
  • 其中,refer()返回的Invoker由协议实现,协议通常需要在此Invoker中发送远程请求,export()传入的Invoker由框架实现并传入,协议不需要关心。

注意

  • 协议不关心业务接口的透明代理,

调用拦截扩展

扩展说明

服务提供方和服务消费方调用过程拦截,Dubbo本身的大多功能均基于此扩展点实现,每次远程方法执行,该拦截器都会被执行,请注意对性能的影响。

约定:

  • 用户自定义filter默认在内置filter之后。
  • 特殊值default,表示缺省扩展点插入的位置。比如:filter="xxx,default,yyy",表示xxx在缺省filter之前,yyy在缺省filter之后。
  • 特殊符合-,表示删除。比如:filter="-fool",删除添加缺省扩展点foo1。比如:filter="-default",剔除添加所有缺省扩展点。
  • provider和service同时配置filter时,累加所有filter,而不是覆盖。比如:<dubbo:provider filter="xxx,yyy" /><dubbo:service filte="aaa,bbb"/>,则xxx,yyy,aaa,bbb均会生效。如果需要覆盖,需配置:<dubbo:service filter="-xxx,-yyy,aaa,bbb"/>
扩展接口
org.apache.dubbo.rpc.Filter
扩展配置
<!-- 消费方调用过程拦截 -->
<dubbo:reference filter="xxx,yyy"/>
<!-- 消费方调用过程缺省拦截器,将拦截所有reference -->
<dubbo:consumer filter="xxx,yyy"/>
<!-- 提供方调用过程拦截 -->
<dubbo:service filter="xxx,yyy"/>
<!-- 提供方调用过程缺省拦截器,将拦截所有的service -->
<dubbo:provider filter="xxx,yyy"/>
已知扩展
  • org.apache.dubbo.rpc.filter.EchoFilter
  • org.apache.dubbo.rpc.filter.GenericFilter
  • org.apache.dubbo.rpc.filter.GenericImplFilter
  • org.apache.dubbo.rpc.filter.TokenFilter
  • org.apache.dubbo.rpc.filter.AccessLogFilter
  • org.apache.dubbo.rpc.filter.ActiveLimitFilter
  • org.apache.dubbo.rpc.filter.ClassLoaderFilter
  • org.apache.dubbo.rpc.filter.ContextFilter
  • org.apache.dubbo.rpc.filter.ExceptionFilter
  • org.apache.dubbo.rpc.filter.ExecuteLimitFilter
  • org.apache.dubbo.rpc.filter.DeprecatedFilter
扩展实例
src|-main|-java|-com|-doudou|- filter|-LogFilter.java (实现Filter接口)|-resources|-META-INF|-dubbo|-org.apache.dubbo.rpc.Filter (纯文本文件,内容为:logFilter=com.doudou.filter.LogFilter)

XxxFilter.java

package com.doudou.filter;import com.alibaba.fastjson2.JSON;
import org.apache.dubbo.rpc.Filter;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class LogFilter implements Filter {private Logger logger = LoggerFactory.getLogger(LogFilter.class);@Overridepublic Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {logger.info("param {}", JSON.toJSONString(invocation.getArguments()));Result result = invoker.invoke(invocation);logger.info("result {}", JSON.toJSONString(result.getValue()));return result;}
}

META-INF/dubbo/org.apache.dubbo.rpc.Filter:

logFilter=com.doudou.filter.LogFilter

DemoServiceImpl.java

package com.doudou.demo.service;import com.doudou.demo.api.DemoService;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;@DubboService(filter = "logFilter")
public class DemoServiceImpl implements DemoService {private Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class);@Overridepublic String sayHello(String name) {logger.info("name:{}", name);return "DemoService "+ "hello " + name;}
}
2025-04-14 11:15:31.809  INFO 20540 --- [:20880-thread-2] com.doudou.filter.LogFilter              : param ["world"]
2025-04-14 11:15:31.809  INFO 20540 --- [:20880-thread-2] com.doudou.demo.service.DemoServiceImpl  : name:world
2025-04-14 11:15:31.811  INFO 20540 --- [:20880-thread-2] com.doudou.filter.LogFilter              : result "DemoService hello world"

引用监听扩展

扩展说明

当有服务引用时,触发该事件。

扩展接口

org.apache.dubbo.rpc.InvokerListener

扩展配置
<!-- 引用服务监听 -->
<dubbo:reference listener="xxx,yyy"/>
<!-- 引用服务缺省监听器 -->
<dubbo:consumer listener="xxx,yyy"/>
已知扩展

org.apache.dubbo.rpc.listener.DeprecatedInvokerListener

扩展实例
src|-main|-java|-com|-doudou|-listener|-DemoListener.java (实现InvokerListener接口)|-resources|-META-INF|-dubbo|-org.apache.dubbo.rpc.InvokerListener (纯文本文件,内容为:demoListener=com.doudou.listener.DemoListener)

DemoListener.java

package com.doudou.listener;import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.InvokerListener;
import org.apache.dubbo.rpc.RpcException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class DemoListener implements InvokerListener {private Logger logger = LoggerFactory.getLogger(DemoListener.class);@Overridepublic void referred(Invoker<?> invoker) throws RpcException {String name = invoker.getInterface().getName();String methodName = invoker.getUrl().getParameter("method");String params = invoker.getUrl().getParameter("params");logger.info("referred interfaceName {}, methodName {}, params {}", name, methodName, params);}@Overridepublic void destroyed(Invoker<?> invoker) {String name = invoker.getInterface().getName();String methodName = invoker.getUrl().getParameter("method");String params = invoker.getUrl().getParameter("params");logger.info("destroyed interfaceName {}, methodName {}, params {}", name, methodName, params);}
}

META-INF/dubbo/org.apache.dubbo.rpc.InvokerListener:
demoListener=com.doudou.listener.DemoListener
Task.java

package com.doudou.demo.Task;import com.doudou.demo.api.DemoService;
import com.doudou.demo.api.HelloService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;@Component
public class Task implements CommandLineRunner {private static final Logger logger = LoggerFactory.getLogger(Task.class);@DubboReference(listener = {"demoListener"})private DemoService demoService;@DubboReference(listener = {"demoListener"})private HelloService helloService;@Overridepublic void run(String... args) throws Exception {String result = demoService.sayHello("world");logger.info("demoService result:{}", result);String world = helloService.hello("world");logger.info("helloService result:{}", world);}
}
2025-04-14 11:52:38.613  INFO 23088 --- [egistryReceiver] com.doudou.listener.DemoListener         : referred interfaceName com.doudou.demo.api.HelloService, methodName null, params null

暴露监听扩展

扩展说明

当有服务暴露时,触发该事件。

扩展接口

org.apache.dubbo.rpc.ExporterListener

扩展配置
<!-- 暴露服务监听 -->
<dubbo:service listener="xxx,yyy"/>
<!-- 暴露服务缺省监听器 -->
<dubbo:provider listener="xxx,yyy"/>
已知扩展

org.apache.dubbo.rpc.listener.InjvmExporterListener

扩展实例
src|-main|-java|-com|-doudou|-listener|-DemoExporterListener.java (实现ExporterListener接口)|-resources|-META-INF|-dubbo|-org.apache.dubbo.rpc.ExporterListener (纯文本文件,内容为:demo=com.doudou.listener.DemoExporterListener)

DemoExporterListener.java

package com.doudou.listener;import com.alibaba.fastjson2.JSON;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Exporter;
import org.apache.dubbo.rpc.ExporterListener;
import org.apache.dubbo.rpc.RpcException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class DemoExporterListener implements ExporterListener {private Logger logger = LoggerFactory.getLogger(DemoExporterListener.class);@Overridepublic void exported(Exporter<?> exporter) throws RpcException {String interfaceName = exporter.getInvoker().getInterface().getName();URL url = exporter.getInvoker().getUrl();String address = url.getAddress();String serviceKey = url.getServiceKey();logger.info("exported interfaceName:{},address:{},serviceKey:{}", interfaceName, address, serviceKey);}@Overridepublic void unexported(Exporter<?> exporter) {String interfaceName = exporter.getInvoker().getInterface().getName();URL url = exporter.getInvoker().getUrl();String address = url.getAddress();String serviceKey = url.getServiceKey();logger.info("unexported interfaceName:{},address:{},serviceKey:{}", interfaceName, address, serviceKey);}
}

META-INF/dubbo/org.apache.dubbo.rpc.ExporterListener:
demoExporterListener=com.doudou.listener.DemoExporterListener

使用

package com.doudou.demo.service;import com.doudou.demo.api.DemoService;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;@DubboService(filter = {"logFilter"}, listener = {"demoExporterListener"})
public class DemoServiceImpl implements DemoService {private Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class);@Overridepublic String sayHello(String name) {logger.info("name:{}", name);return "DemoService "+ "hello " + name;}
}
2025-04-14 13:58:11.131  INFO 26080 --- [           main] c.doudou.listener.DemoExporterListener   : exported interfaceName:com.doudou.demo.api.DemoService,address:10.1.6.137:50051,serviceKey:com.doudou.demo.api.DemoService

集群扩展

扩展说明

当有多个服务提供方时,将多个服务提供方组装成一个集群,并伪装成一个提供方。

扩展接口

org.apache.dubbo.rpc.cluster.Cluster

扩展配置
<dubbo:protocol cluster="xxx"/>
<!-- 缺省值配置,如果<dubbo:protocol>没有配置cluster时,使用此配置。-->
<dubbo:provider cluster="xxx"/>
已知扩展
  • org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterWrapper
  • org.apache.dubbo.rpc.cluster.support.FailoverCluster
  • org.apache.dubbo.rpc.cluster.support.FailfastCluster
  • org.apache.dubbo.rpc.cluster.support.FailsafeCluster
  • org.apache.dubbo.rpc.cluster.support.FailbackCluster
  • org.apache.dubbo.rpc.cluster.support.ForkingCluster
  • org.apache.dubbo.rpc.cluster.support.AvailableCluster
  • org.apache.dubbo.rpc.cluster.support.MergeableCluster
  • org.apache.dubbo.rpc.cluster.support.BroadcastCluster
  • org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareCluster
扩展实例
src|-main|-java|-com|-doudou|-invoker|-MyClusterInvoker.java(必须集成AbstractClusterInvoker抽象类)|-cluster|-MyCluster.java (实现org.apache.dubbo.rpc.cluster.Cluster接口)|-resources|-META-INF|-dubbo|-org.apache.dubbo.rpc.cluster.Cluster (纯文本文件,内容为:myCluster=com.doudou.cluster.MyCluster)
package com.doudou.invoker;import java.util.List;
import java.util.Random;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.cluster.Directory;
import org.apache.dubbo.rpc.cluster.LoadBalance;
import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** @author admin*/
public class MyClusterInvoker<T> extends AbstractClusterInvoker<T> {private Logger logger = LoggerFactory.getLogger(MyClusterInvoker.class);Random random = new Random();public MyClusterInvoker(Directory<T> directory) {super(directory);}@Overrideprotected Result doInvoke(Invocation invocation, List<Invoker<T>> invokers,LoadBalance loadbalance) throws RpcException {int num = random.nextInt(invokers.size());logger.info("invoke num: {}", num);Invoker<T> invoker = invokers.get(num);return invoker.invoke(invocation);}
}
package com.doudou.cluster;import com.doudou.invoker.MyClusterInvoker;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.cluster.Cluster;
import org.apache.dubbo.rpc.cluster.Directory;/*** @author admin*/
public class MyCluster implements Cluster {@Overridepublic <T> Invoker<T> join(Directory<T> directory, boolean buildFilterChain)throws RpcException {return new MyClusterInvoker<>(directory);}
}

org.apache.dubbo.rpc.cluster.Cluster
myCluster=com.doudou.cluster.MyCluster

使用

dubbo:consumer:cluster: myCluster

package com.doudou.task;import com.doudou.service.api.DemoService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;/*** @author admin*/
@Component
public class Task01 implements CommandLineRunner {private Logger logger = LoggerFactory.getLogger(Task01.class);@DubboReference(cluster = "myCluster")private DemoService demoService;@Overridepublic void run(String... args) throws Exception {for (int i = 0; i < 10; i++) {String result = demoService.sayHello("zhangsan");logger.info("result {}", result);}}
}

路由扩展

扩展说明

从多个服务提供方中选择一个进行调用

扩展接口
  • org.apache.dubbo.rpc.cluster.RouterFactory
  • org.apache.dubbo.rpc.cluster.Router
扩展实例
src|-main|-java|-com|-doudou|-route|-GrayRouter.java(实现Router或继承AbstractRouter类)|-cluster|-GrayRouterFactory.java (实现org.apache.dubbo.rpc.cluster.RouterFactory接口)|-resources|-META-INF|-dubbo|-org.apache.dubbo.rpc.cluster.RouterFactory (纯文本文件,内容为:gray=com.doudou.router.GrayRouterFactory)
package com.doudou.router;import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.cluster.router.AbstractRouter;
import org.apache.dubbo.rpc.cluster.router.RouterResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;/*** @title CustomRouter* @description <TODO description class purpose>* author zzw* version 1.0.0* create 2025/4/15 22:21**/
public class GrayRouter extends AbstractRouter {private Logger logger = LoggerFactory.getLogger(GrayRouter.class);@Overridepublic <T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {String grayFlag = invocation.getAttachments().get("env");return invokers.stream().filter(invoker ->{String envStr = invoker.getUrl().getParameter("env");logger.info("envStr:{}", envStr);return envStr.equals(Objects.isNull(grayFlag) ? "prod" : "gray");}).collect(Collectors.toList());}
}
package com.doudou.router;import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.cluster.Router;
import org.apache.dubbo.rpc.cluster.RouterFactory;/*** @title CustomRouterFactory* @description <TODO description class purpose>* author zzw* version 1.0.0* create 2025/4/15 22:22**/
@Activate(order = 100, group = "consumer")
public class GrayRouterFactory implements RouterFactory {@Overridepublic Router getRouter(URL url) {return new GrayRouter();}
}

org.apache.dubbo.rpc.cluster.RouterFactory
gray=com.doudou.router.GrayRouterFactory

使用

dubbo:provider:parameters:env: "gray"
conditions:- => env=gray

负载均衡扩展

扩展说明

从多个服务提供方中选择一个进行调用

扩展接口

org.apache.dubbo.rpc.cluster.LoadBalance

扩展配置
dubbo:# 服务提供者配置provider:loadbalance: xxx# 服务消费者配置consumer:loadbalance: xxx
已知配置
  • org.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance
  • org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance
  • org.apache.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance
  • org.apache.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalance
  • org.apache.dubbo.rpc.cluster.loadbalance.ShortestResponseLoadBalance
扩展实例
src|-main|-java|-com|-doudou|-loadbalance|-WeightRandomLoadBalance.java(实现LoadBalance或继承AbstractLoadBalance类)|-resources|-META-INF|-dubbo|-org.apache.dubbo.rpc.cluster.LoadBalance (纯文本文件,内容为:weight-random=com.doudou.demo.loadbalance.WeightRandomLoadBalance)
package com.doudou.demo.loadbalance;import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.cluster.loadbalance.AbstractLoadBalance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.List;
import java.util.concurrent.ThreadLocalRandom;/*** @title WeightRandomLoadBalance* @description 实现基于权重的随机选择* author zzw* version 1.0.0* create 2025/4/15 23:29**/
public class WeightRandomLoadBalance extends AbstractLoadBalance {private Logger logger = LoggerFactory.getLogger(WeightRandomLoadBalance.class);@Overrideprotected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {int totalWeight = invokers.stream().mapToInt(invoker -> invoker.getUrl().getParameter("weight", 100)).sum();logger.info("total weight:{}", totalWeight);int random = ThreadLocalRandom.current().nextInt(totalWeight);logger.info("random:{}", random);for (Invoker<T> invoker : invokers) {random -= invoker.getUrl().getParameter("weight", 100);logger.info("random:{}", random);if (random < 0) {return invoker;}}return invokers.get(0);}
}

org.apache.dubbo.rpc.cluster.LoadBalance
weight-random=com.doudou.demo.loadbalance.WeightRandomLoadBalance

package com.doudou.demo.task;import com.doudou.demo.api.DemoService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.rpc.RpcContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;/*** @title Task01* @description <TODO description class purpose>* author zzw* version 1.0.0* create 2025/4/15 21:32**/
@Component
public class Task01 implements CommandLineRunner {private Logger logger = LoggerFactory.getLogger(Task01.class);@DubboReference(loadbalance = "weight-random")private DemoService demoService;@Overridepublic void run(String... args) throws Exception {for (int i = 0; i < 10; i++) {RpcContext.getClientAttachment().setAttachment("env", "gray1");String result = demoService.sayHello("provider " + i);logger.info("{} --->> {}", i, result);}}
}

dubbo:# 服务提供者配置provider:loadbalance: weight-random# 服务消费者配置 优先级高于服务提供者配置consumer:loadbalance: weight-random

合并结果扩展

扩展说明

合并返回的结果,用于分组聚合。

扩展接口

org.apache.dubbo.rpc.cluster.Merger

扩展配置

<dubbo:method merge="xxx"/>

@DubboReference(group = "*", merger = "true", methods = @Method(name = "sayHello", merger = "customListMerger"))
private DemoService demoService;
已知扩展
  • org.apache.dubbo.rpc.cluster.merger.ArrayMerger
  • org.apache.dubbo.rpc.cluster.merger.BooleanArrayMerger
  • org.apache.dubbo.rpc.cluster.merger.ByteArrayMerger
  • org.apache.dubbo.rpc.cluster.merger.CharArrayMerger
  • org.apache.dubbo.rpc.cluster.merger.DoubleArrayMerger
  • org.apache.dubbo.rpc.cluster.merger.FloatArrayMerger
  • org.apache.dubbo.rpc.cluster.merger.IntArrayMerger
  • org.apache.dubbo.rpc.cluster.merger.ListMerger
  • org.apache.dubbo.rpc.cluster.merger.LongArrayMerger
  • org.apache.dubbo.rpc.cluster.merger.MapMerger
  • org.apache.dubbo.rpc.cluster.merger.MergerFactory
  • org.apache.dubbo.rpc.cluster.merger.SetMerger
  • org.apache.dubbo.rpc.cluster.merger.ShortArrayMerger
扩展实例
src|-main|-java|-com|-demo|-CustomListMerger.java 实现Merger接口|-resources|-META-INF|-dubbo|-org.apache.dubbo.rpc.cluster.Merger (纯文本文件,内容为:customListMerger=com.doudou.demo.merger.CustomListMerger)

CustomListMerger.java

package com.doudou.demo.merger;import com.alibaba.fastjson2.JSON;
import org.apache.dubbo.rpc.cluster.Merger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** @title CustomListMerger* @description <TODO description class purpose>* author zzw* version 1.0.0* create 2025/4/16 20:37**/
public class CustomListMerger<T> implements Merger<T> {private Logger logger = LoggerFactory.getLogger(CustomListMerger.class);@Overridepublic T merge(T... items) {logger.info(" -------------------------- items {}", JSON.toJSONString(items));return items[0];}
}

org.apache.dubbo.rpc.cluster.Merger

customListMerger=com.doudou.demo.merger.CustomListMerger
@DubboReference(group = "*", merger = "true", methods = @Method(name = "sayHello", merger = "customListMerger"))
private DemoService demoService;

注册中心扩展

扩展说明

负责服务的注册与发现

扩展接口
  • org.apache.dubbo.registry.RegistryFactory
  • org.apache.dubbo.registry.Registry
扩展配置
<!-- 定义注册中心 -->
<dubbo:registry id="xxx1" address="xxx://ip:port" />
<!-- 引用注册中心。如果没有配置registry属性,将在ApplicationContext中自动扫描registry配置 -->
<dubbo:service registry="xxx1" />
<!-- 引用注册中心缺省值,当<dubbo:service>没有配置registry时,使用此配置 -->
<dubbo:provider registry="xxx1" />
扩展

RegistryFactory.java:

import java.net.URL;public interface RegistryFactory {/*** 连接注册中心** 连接注册中心需处理契约:* 1. 当设置check=false时表示不检查连接,否则连接不上时抛出异常。* 2. 支持URL上的username:password权限认证。* 3. 支持backup=10.20.111.10备选注册中心集群地址。* 4. 支持file=registry.cache本地磁盘文件缓存。* 5. 支持timeout=1000请求超时设置。* 6. 支持session=60000会话超时或过期设置。** @param url 注册中心地址,不允许为空* @return 注册中心引用,总不返回空*/Registry getRegistry(URL url);
}

RegistryService.java:

ublic interface RegistryService { // Registry extends RegistryService /*** 注册服务.* * 注册需处理契约:<br>* 1. 当URL设置了check=false时,注册失败后不报错,在后台定时重试,否则抛出异常。<br>* 2. 当URL设置了dynamic=false参数,则需持久存储,否则,当注册者出现断电等情况异常退出时,需自动删除。<br>* 3. 当URL设置了category=overrides时,表示分类存储,缺省类别为providers,可按分类部分通知数据。<br>* 4. 当注册中心重启,网络抖动,不能丢失数据,包括断线自动删除数据。<br>* 5. 允许URI相同但参数不同的URL并存,不能覆盖。<br>* * @param url 注册信息,不允许为空,如:dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin*/void register(URL url);/*** 取消注册服务.* * 取消注册需处理契约:<br>* 1. 如果是dynamic=false的持久存储数据,找不到注册数据,则抛IllegalStateException,否则忽略。<br>* 2. 按全URL匹配取消注册。<br>* * @param url 注册信息,不允许为空,如:dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin*/void unregister(URL url);/*** 订阅服务.* * 订阅需处理契约:<br>* 1. 当URL设置了check=false时,订阅失败后不报错,在后台定时重试。<br>* 2. 当URL设置了category=overrides,只通知指定分类的数据,多个分类用逗号分隔,并允许星号通配,表示订阅所有分类数据。<br>* 3. 允许以interface,group,version,classifier作为条件查询,如:interface=com.alibaba.foo.BarService&version=1.0.0<br>* 4. 并且查询条件允许星号通配,订阅所有接口的所有分组的所有版本,或:interface=*&group=*&version=*&classifier=*<br>* 5. 当注册中心重启,网络抖动,需自动恢复订阅请求。<br>* 6. 允许URI相同但参数不同的URL并存,不能覆盖。<br>* 7. 必须阻塞订阅过程,等第一次通知完后再返回。<br>* * @param url 订阅条件,不允许为空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin* @param listener 变更事件监听器,不允许为空*/void subscribe(URL url, NotifyListener listener);/*** 取消订阅服务.* * 取消订阅需处理契约:<br>* 1. 如果没有订阅,直接忽略。<br>* 2. 按全URL匹配取消订阅。<br>* * @param url 订阅条件,不允许为空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin* @param listener 变更事件监听器,不允许为空*/void unsubscribe(URL url, NotifyListener listener);/*** 查询注册列表,与订阅的推模式相对应,这里为拉模式,只返回一次结果。* * @see org.apache.dubbo.registry.NotifyListener#notify(List)* @param url 查询条件,不允许为空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin* @return 已注册信息列表,可能为空,含义同{@link org.apache.dubbo.registry.NotifyListener#notify(List<URL>)}的参数。*/List<URL> lookup(URL url);

NotifyListener.java:

public interface NotifyListener { /*** 当收到服务变更通知时触发。* * 通知需处理契约:<br>* 1. 总是以服务接口和数据类型为维度全量通知,即不会通知一个服务的同类型的部分数据,用户不需要对比上一次通知结果。<br>* 2. 订阅时的第一次通知,必须是一个服务的所有类型数据的全量通知。<br>* 3. 中途变更时,允许不同类型的数据分开通知,比如:providers, consumers, routes, overrides,允许只通知其中一种类型,但该类型的数据必须是全量的,不是增量的。<br>* 4. 如果一种类型的数据为空,需通知一个empty协议并带category参数的标识性URL数据。<br>* 5. 通知者(即注册中心实现)需保证通知的顺序,比如:单线程推送,队列串行化,带版本对比。<br>* * @param urls 已注册信息列表,总不为空,含义同{@link org.apache.dubbo.registry.RegistryService#lookup(URL)}的返回值。*/void notify(List<URL> urls);}
已知扩展
  • org.apache.dubbo.registry.nacos.NacosRegistryFactory
  • org.apache.dubbo.registry.zookeeper.ZookeeperRegistryFactory
  • org.apache.dubbo.registry.multicast.MulticastRegistryFactory

监控中心扩展

扩展说明

负责服务调用次数和调用时间的监控

扩展接口
  • org.apache.dubbo.monitor.MonitorFactory
  • org.apache.dubbo.monitor.Monitor
扩展配置
<!-- 定义监控中心 -->
<dubbo:monitor address="xxx://ip:port" />
已知扩展

org.apache.dubbo.monitor.dubbo.DubboMonitorFactory

动态代理扩展

扩展说明

Invoker接口转换成业务接口。

扩展接口

org.apache.dubbo.rpc.ProxyFactory

扩展配置
<dubbo:protocol proxy="xxx"/>
<!-- 缺省值配置,当<dubbo:protocol>没有配置proxy属性时,使用此配置 -->
<dubbo:provider proxy="xxx"/>
已知扩展
  • org.apache.dubbo.rpc.proxy.jdk.JdkProxyFactory
    • 基于JDK原生动态代理,兼容性更强
  • org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory
    • 基于字节码生成,性能更高
扩展实现
package com.doudou.demo.proxy;import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.model.ServiceModel;
import org.apache.dubbo.rpc.proxy.AbstractProxyFactory;
import org.apache.dubbo.rpc.proxy.AbstractProxyInvoker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.UUID;@Activate(order = -10000) // 高优先级激活扩展
public class TracingProxyFactory extends AbstractProxyFactory {private static final Logger logger = LoggerFactory.getLogger(TracingProxyFactory.class);private static final String TRACE_ID_KEY = "traceId";// 消费者端代理增强@SuppressWarnings("unchecked")@Overridepublic <T> T getProxy(Invoker<T> invoker, Class<?>[] types) {Class<?> interfaceClass = invoker.getInterface();return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(),new Class[]{interfaceClass},(proxy, method, args) -> {RpcContext clientContext = RpcContext.getClientAttachment();String traceId = clientContext.getAttachment(TRACE_ID_KEY);// 生成或透传 traceIdif (traceId == null) {traceId = generateTraceId(); // 自定义生成规则‌:ml-citation{ref="3,5" data="citationList"}clientContext.setAttachment(TRACE_ID_KEY, traceId);}logger.info("traceId : {}", traceId);MDC.put(TRACE_ID_KEY, traceId); // 绑定到日志上下文‌:ml-citation{ref="7,8" data="citationList"}logger.info("[Dubbo-Consumer] {}.{} args={}",interfaceClass.getSimpleName(), method.getName(), args);long start = System.currentTimeMillis();try {URL invokerUrl = invoker.getUrl();ServiceModel serviceModel = invokerUrl.getServiceModel();String protocolServiceKey = invokerUrl.getProtocolServiceKey();RpcInvocation rpcInvocation = new RpcInvocation(serviceModel, method.getName(),invoker.getInterface().getName(), protocolServiceKey, method.getParameterTypes(), args);Object result = invoker.invoke(rpcInvocation).recreate();logger.info("[Dubbo-Consumer] {}.{} return={}",interfaceClass.getSimpleName(), method.getName(), result);return result;} catch (Exception e) {logger.error("[Dubbo-Consumer] {}.{} error={}",interfaceClass.getSimpleName(), method.getName(), e.getMessage(), e);throw e;} finally {logger.debug("[Dubbo-Consumer] {}.{} cost={}ms",interfaceClass.getSimpleName(), method.getName(),System.currentTimeMillis() - start);MDC.remove(TRACE_ID_KEY); // 清理上下文‌:ml-citation{ref="7,8" data="citationList"}}});}// 服务提供者端 Invoker 增强@Overridepublic <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {return new AbstractProxyInvoker<T>(proxy, type, url) {@Overrideprotected Object doInvoke(T proxy, String methodName,Class<?>[] paramTypes, Object[] args) throws Throwable {Method method = proxy.getClass().getMethod(methodName, paramTypes);RpcContext serverContext = RpcContext.getServerAttachment();String traceId = serverContext.getAttachment(TRACE_ID_KEY);logger.info("traceId : {}", traceId);MDC.put(TRACE_ID_KEY, traceId); // 透传 traceId:ml-citation{ref="5,8" data="citationList"}logger.info("[Dubbo-Provider] {}.{} args={}",type.getSimpleName(), methodName, args);long start = System.currentTimeMillis();try {Object result = method.invoke(proxy, args);logger.info("[Dubbo-Provider] {}.{} return={}",type.getSimpleName(), methodName, result);return result;} catch (Exception e) {logger.error("[Dubbo-Provider] {}.{} error={}",type.getSimpleName(), methodName, e.getMessage(), e);throw e;} finally {logger.debug("[Dubbo-Provider] {}.{} cost={}ms",type.getSimpleName(), methodName,System.currentTimeMillis() - start);MDC.remove(TRACE_ID_KEY); // 清理上下文‌:ml-citation{ref="7,8" data="citationList"}}}};}// TraceId 生成规则(UUID 精简版)private String generateTraceId() {return UUID.randomUUID().toString().replace("-", "").substring(0, 16);}
}

META-INF/dubbo/org.apache.dubbo.rpc.ProxyFactory

tracing=com.doudou.demo.proxy.TracingProxyFactory
@DubboReference(proxy = "tracing")
private DemoService demoService;@DubboService(proxy = "tracing")
public class DemoServiceImpl implements DemoService {}

或全局配置

dubbo:provider:proxy: tracing
---
dubbo:consumer:proxy: tracing

Readiness 就绪探针

扩展说明

扩展应用就绪的监测点。
Readiness 探针用于检测容器是否已准备好接收外部请求。
当探针检查失败时,Pod 的 IP 地址会从关联 Service 的 Endpoints 列表中移除,确保流量不会转发到未就绪的容器实例‌。
确保容器完成初始化(如依赖服务连接、配置加载、数据预热等)后才开放服务请求,避免因未就绪实例处理请求导致业务异常‌

扩展接口

org.apache.dubbo.qos.probe.ReadinessProbe

扩展配置

Dubbo QOS ready命令自动发现

已知扩展
  • org.apache.dubbo.qos.probe.impl.ProviderReadinessProbe
  • org.apache.dubbo.qos.probe.impl.DeployerReadinessProbe
扩展实例

DatabaseReadinessProbe.java

package com.doudou.demo.readiness;import org.apache.dubbo.qos.probe.ReadinessProbe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** @title DatabaseReadinessProbe* @description 验证数据库连接池是否可用,防止因连接泄漏或数据库宕机导致服务不可用。* author zzw* version 1.0.0* create 2025/4/20 18:08**/
public class DatabaseReadinessProbe implements ReadinessProbe {private Logger logger = LoggerFactory.getLogger(DatabaseReadinessProbe.class);@Overridepublic boolean check() {logger.info("DatabaseReadinessProbe check");// 自定义实现return false;}
}

RedisHealthReadinessProbe.java

package com.doudou.demo.readiness;import org.apache.dubbo.qos.probe.ReadinessProbe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** @title RedisHealthProbe* @description 确保 Redis 集群连接正常,避免缓存服务不可用影响业务逻辑。* author zzw* version 1.0.0* create 2025/4/20 18:12**/
public class RedisHealthReadinessProbe implements ReadinessProbe {private Logger logger = LoggerFactory.getLogger(RedisHealthReadinessProbe.class);@Overridepublic boolean check() {logger.info("Redis health check");// 自定义实现return false;}
}

/META-INF/dubbo/org.apache.dubbo.qos.probe.ReadinessProbe

dbCheck=com.doudou.demo.readiness.DatabaseReadinessProbe
redisCheck=com.doudou.demo.readiness.RedisHealthReadinessProbe

application.properties

dubbo.application.readiness-probe: dbCheck,redisCheck

Startup 启动探针

扩展说明

扩展应用启动的监测点

扩展接口

org.apache.dubbo.qos.probe.StartupProbe

扩展配置

Dubbo QOS startup命令自动发现

已知扩展

org.apache.dubbo.qos.probe.impl.DeployerStartupProbe

编译器扩展

扩展说明

Java代码编译器,用于动态生成字节码,加速调用

扩展接口

org.apache.dubbo.common.compiler.Compiler

扩展配置

自动加载

已知扩展
  • org.apache.dubbo.common.compiler.support.JavassistCompiler
  • org.apache.dubbo.common.compiler.support.JdkCompiler

配置中心扩展

设计目的

配置中心的核心功能是作为 Key-Value 存储,Dubbo 框架告知配置中心其关心的 key,配置中心返回该key对应的 value 值。

按照应用场景划分,配置中心在 Dubbo 框架中主要承担以下职责:

  • 作为外部化配置中心,即存储 dubbo.properties 配置文件,此时,key 值通常为文件名如 dubbo.properties,value 则为配置文件内容。
  • 存储单个配置项,如各种开关项、常量值等。
  • 存储服务治理规则,此时key通常按照 “服务名+规则类型” 的格式来组织,而 value 则为具体的治理规则。

为了进一步实现对 key-value 的分组管理,Dubbo 的配置中心还加入了 namespace、group 的概念,这些概念在很多专业的第三方配置中心中都有体现,通常情况下,namespace 用来隔离不同的租户,group 用来对同一租户的key集合做分组。

扩展接口
  • org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
  • org.apache.dubbo.common.config.configcenter.DynamicConfiguration
已知扩展
  • org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfigurationFactory
  • org.apache.dubbo.configcenter.support.nacos.NacosDynamicConfigurationFactory
  • org.apache.dubbo.configcenter.support.apollo.ApolloDynamicConfigurationFactory
  • org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfigurationFactory

元数据中心扩展

扩展接口
  • org.apache.dubbo.metadata.report.MetadataReportFactory
  • org.apache.dubbo.metadata.report.MetadataReport
已知扩展
  • org.apache.dubbo.metadata.store.nacos.NacosMetadataReportFactory
  • org.apache.dubbo.metadata.store.redis.RedisMetadataReportFactory
  • org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReportFactory

消息派发扩展

扩展说明

通道消息派发器,用于指定线程池模型

扩展接口

org.apache.dubbo.remoting.Dispatcher

扩展配置
<dubbo:protocol dispatcher="xxx" />
<!-- 缺省值设置,当<dubbo:protocol>没有配置dispatcher属性时,使用此配置 -->
<dubbo:provider dispatcher="xxx" />
已知扩展
  • org.apache.dubbo.remoting.transport.dispatcher.all.AllDispatcher
  • org.apache.dubbo.remoting.transport.dispatcher.direct.DirectDispatcher.dispatch
  • org.apache.dubbo.remoting.transport.dispatcher.message.MessageOnlyDispatcher.dispatch
  • org.apache.dubbo.remoting.transport.dispatcher.execution.ExecutionDispatcher
  • org.apache.dubbo.remoting.transport.dispatcher.connection.ConnectionOrderedDispatcher

线程池扩展

扩展说明

服务提供方线程池实现策略,当服务器收到一个请求时,需要在线程池中创建一个线程去执行服务提供方业务逻辑。

扩展接口

org.apache.dubbo.common.threadpool.ThreadPool

扩展配置
<dubbo:protocol threadpool="xxx" />
<!-- 缺省值设置,当<dubbo:protocol>没有配置threadpool时,使用此配置 -->
<dubbo:provider threadpool="xxx" />
已知扩展
  • org.apache.dubbo.common.threadpool.support.limited.LimitedThreadPool
  • org.apache.dubbo.common.threadpool.support.fixed.FixedThreadPool
  • org.apache.dubbo.common.threadpool.support.eager.EagerThreadPool
  • org.apache.dubbo.common.threadpool.support.cached.CachedThreadPool

序列化扩展

扩展说明

将对象转成字节流,用于网络传输,以及将字节流转为对象,用于在收到字节流数据后还原成对象。

扩展接口
  • org.apache.dubbo.common.serialize.Serialization
  • org.apache.dubbo.common.serialize.ObjectInput
  • org.apache.dubbo.common.serialize.ObjectOutput
扩展配置
<!-- 协议的序列化方式 -->
<dubbo:protocol serialization="xxx" />
<!-- 缺省值设置,当<dubbo:protocol>没有配置serialization时,使用此配置 -->
<dubbo:provider serialization="xxx" />
已知扩展
  • org.apache.dubbo.common.serialize.hessian2.Hessian2Serialization
  • org.apache.dubbo.common.serialize.java.JavaSerialization
  • org.apache.dubbo.common.serialize.nativejava.NativeJavaSerialization
  • org.apache.dubbo.common.serialize.fastjson2.FastJson2Serialization
  • org.apache.dubbo.common.serialize.java.CompactedJavaSerialization

网络传输扩展

扩展说明

远程通讯的服务器及客户端传输实现。

扩展接口
  • org.apache.dubbo.remoting.Transporter
  • org.apache.dubbo.remoting.RemotingServer
  • org.apache.dubbo.remoting.Client
扩展配置
<!-- 服务器和客户端使用相同的传输实现 -->
<dubbo:protocol transporter="xxx" /> 
<!-- 服务器和客户端使用不同的传输实现 -->
<dubbo:protocol server="xxx" client="xxx" /> 
<!-- 缺省值设置,当<dubbo:protocol>没有配置transporter/server/client属性时,使用此配置 -->
<dubbo:provider transporter="xxx" server="xxx" client="xxx" />
已知扩展
  • org.apache.dubbo.remoting.transport.netty4.NettyTransporter

信息交换扩展

扩展说明

基于传输层之上,实现Request-Response信息交换语义。

扩展接口
  • org.apache.dubbo.remoting.exchange.Exchanger
  • org.apache.dubbo.remoting.exchange.ExchangeServer
  • org.apache.dubbo.remoting.exchange.ExchangeClient
扩展配置
<dubbo:protocol exchanger="xxx" />
<!-- 缺省值设置,当<dubbo:protocol>没有配置exchanger属性时,使用此配置 -->
<dubbo:provider exchanger="xxx" />
已知扩展

org.apache.dubbo.remoting.exchange.support.header.HeaderExchanger

对等网络节点组网器扩展

扩展说明

对等网络节点组网器

扩展接口

com.alibaba.dubbo.container.page.PageHandler

扩展配置
<dubbo:protocol page="xxx,yyy" />
<!-- 缺省值设置,当<dubbo:protocol>没有配置page属性时,使用此配置 -->
<dubbo:provider page="xxx,yyy" />
已知扩展
  • com.alibaba.dubbo.container.page.pages.StatusPageHandler
  • com.alibaba.dubbo.container.page.pages.HomePageHandler
  • com.alibaba.dubbo.container.page.pages.LogPageHandler
  • com.alibaba.dubbo.container.page.pages.SystemPageHandler

Telnet 命令扩展

扩展说明

所有服务均支持telnet访问,用于人工干预

扩展接口

org.apache.dubbo.remoting.telnet.TelnetHandler

扩展配置
<dubbo:protocol telnet="xxx,yyy" />
<!-- 缺省值设置,当<dubbo:protocol>没有配置telnet属性时,使用此配置 -->
<dubbo:provider telnet="xxx,yyy" />
已知扩展
  • org.apache.dubbo.remoting.telnet.support.command.ClearTelnetHandler
  • org.apache.dubbo.remoting.telnet.support.command.ExitTelnetHandler
  • org.apache.dubbo.remoting.telnet.support.command.HelpTelnetHandler
  • org.apache.dubbo.remoting.telnet.support.command.StatusTelnetHandler
  • org.apache.dubbo.qos.legacy.ChangeTelnetHandler
  • org.apache.dubbo.qos.legacy.TraceTelnetHandler

状态检查扩展

扩展说明

检查服务依赖各种资源的状态,此状态检查可同时用于telnet的status命令和hosting的status页面。

扩展接口

org.apache.dubbo.common.status.StatusChecker

扩展配置
<dubbo:protocol status="xxx,yyy" />
<!-- 缺省值设置,当<dubbo:protocol>没有配置status属性时,使用此配置 -->
<dubbo:provider status="xxx,yyy" />
已知扩展
  • org.apache.dubbo.common.status.support.MemoryStatusChecker
  • org.apache.dubbo.common.status.support.LoadStatusChecker
  • org.apache.dubbo.rpc.protocol.dubbo.status.ServerStatusChecker
  • org.apache.dubbo.rpc.protocol.dubbo.status.ThreadPoolStatusChecker
  • org.apache.dubbo.registry.status.RegistryStatusChecker
  • org.apache.dubbo.config.spring.status.SpringStatusChecker
  • org.apache.dubbo.config.spring.status.DataSourceStatusChecker

缓存扩展

扩展说明

用请求参数作为key,缓存返回结果

扩展接口

org.apache.dubbo.cache.CacheFactory

扩展配置
<dubbo:service cache="lru" />
<!-- 方法级缓存 -->
<dubbo:service><dubbo:method cache="lru" /></dubbo:service> 
<!-- 缺省值设置,当<dubbo:service>没有配置cache属性时,使用此配置 -->
<dubbo:provider cache="xxx,yyy" /> 
已知扩展
  • org.apache.dubbo.cache.support.lfu.LfuCacheFactory
  • org.apache.dubbo.cache.support.lru.LruCacheFactory
  • org.apache.dubbo.cache.support.jcache.JCacheFactory
  • org.apache.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory

验证扩展

扩展说明

参数验证扩展点。

扩展接口

org.apache.dubbo.validation.Validation

扩展配置
<dubbo:service validation="xxx,yyy" />
<!-- 缺省值设置,当<dubbo:service>没有配置validation属性时,使用此配置 -->
<dubbo:provider validation="xxx,yyy" />
已知扩展
  • org.apache.dubbo.validation.support.jvalidation.JValidation
  • org.apache.dubbo.validation.support.jvalidation.JValidationNew

日志适配扩展

扩展说明

日志输出适配扩展点

扩展接口

org.apache.dubbo.common.logger.LoggerAdapter

扩展配置
<dubbo:application logger="xxx" />

-Ddubbo:application.logger=xxx
已知实例
  • org.apache.dubbo.common.logger.slf4j.Slf4jLoggerAdapter
  • org.apache.dubbo.common.logger.log4j2.Log4j2LoggerAdapter
  • org.apache.dubbo.common.logger.jcl.JclLoggerAdapter
  • org.apache.dubbo.common.logger.jdk.JdkLoggerAdapter
  • org.apache.dubbo.common.logger.log4j.Log4jLoggerAdapter

相关文章:

  • Python变量全解析:从基础到高级的命名规则与数据类型指南
  • 一招破敌,掌控 React 渲染术:createRoot 与 root.render
  • 信创时代编程开发语言选择指南:国产替代背景下的技术路径与实践建议
  • Java学习手册:Filter 和 Listener
  • SSM--AOP 日志
  • 2025/4/20 实验作业 linux系统权限相关实验
  • 股票分析技术指标【MACD】
  • 集合框架(重点)
  • ThreadLocal - 原理与应用场景详解
  • 解决IDEA创建SpringBoot项目没有Java版本8
  • 冠珠瓷砖X2025佛山潭洲陶瓷展主题论坛·AI+未来专场精彩回顾
  • javase 学习
  • Linux驱动开发--异步通知与异步I/O
  • Linux——SSH
  • Transformer系列(二):自注意力机制框架
  • 算法篇之单调栈
  • 如何一键批量删除多个 Word 文档中的页眉和页脚
  • 656SJBH重金属音乐点歌系统
  • Linux下加载可执行文件所在目录下的so的方法
  • rk3568build-linux.sh解析
  • 动力电池、风光电设备退役潮来袭,国家队即将推出“再生计划”
  • 高架上2名儿童从轿车天窗探出身来,驾驶员被记3分罚200元
  • 中办、国办印发《农村基层干部廉洁履行职责规定》
  • 占比超1/3,江苏何以连续多年霸榜“千亿县”?
  • 汕头22岁女子手术成功却意外脑死亡,家属称缺氧30分钟医生未发觉
  • 祥源文旅:2024年营业收入约8.64亿元,今年旅游经济总体预期更为乐观