【Dubbo原理】(二)深入解析Dubbo扩展点加载机制与实战应用
1. 从“找插件”到“造插件”理解Dubbo扩展点加载机制上次我们聊了Dubbo的微内核架构和SPI机制知道了Dubbo就像一个功能强大的“电脑主板”而各种协议、负载均衡策略、过滤器就像是插在主板上的“显卡”、“内存条”。但光知道主板能插东西还不够我们得搞清楚它是怎么识别、怎么安装这些配件的。这就是今天要深入探讨的Dubbo扩展点加载机制核心就是那个神秘的ExtensionLoader。我刚开始看源码的时候也觉得很绕。为什么我配一个loadbalancerandomDubbo就能精准地找到随机负载均衡的实现类为什么我自定义一个Filter只需要在配置文件里写个名字就能生效这背后都是ExtensionLoader在默默工作。简单来说它就是Dubbo框架里那个最勤劳的“插件管理员”负责根据你的指令找到、创建并组装好你需要的那个插件。这个机制的重要性在于它让Dubbo的“高度可扩展”不再是一句空话。无论是阿里巴巴内部还是我们自己的业务都基于这套机制做了大量的定制化。比如我遇到过需要对接一个老旧的消息队列它的协议不是标准的。我们就是通过扩展Protocol接口实现了一套自定义的RPC协议无缝集成到了现有的Dubbo体系中其他服务调用方完全无感知。这种“开箱即用”和“深度定制”的平衡就是扩展点加载机制的功劳。所以这篇文章我们不只讲原理更要讲实战。我会带你一步步拆解ExtensionLoader的工作流程看看“自适应扩展”这个听起来很玄乎的概念到底是怎么实现的最后再手把手教你如何利用这套机制打造属于你自己的Dubbo组件。你会发现理解了它你不仅能更好地使用Dubbo更能拥有改造它的能力。2. 庖丁解牛ExtensionLoader的工作流程全解析ExtensionLoader是Dubbo SPI机制的核心引擎。它的工作目标很明确给你一个接口比如LoadBalance再给你一个名字比如random它就能返回一个配置好的、立即可用的实现类对象。这个过程看似简单内部却像一条精密的流水线。2.1 第一步获取“管理员”本身当你写下ExtensionLoader.getExtensionLoader(LoadBalance.class)这行代码时发生了什么它并不是直接去加载实现类而是先获取管理LoadBalance这个接口的专属“管理员”ExtensionLoader实例。这里用了一个缓存机制ConcurrentMapClass?, ExtensionLoader?。每个扩展点接口类型在Dubbo运行期间全局只会有一个对应的ExtensionLoader实例。这很好理解就像公司里每个部门只有一个经理来管理该部门的所有员工一样避免了重复创建和管理混乱。获取到这个“管理员”后我们才能通过它去进行后续的具体操作。2.2 第二步按图索骥——读取与解析配置文件拿到了“管理员”现在告诉它我要找哪个“员工”扩展实现。比如调用getExtension(random)。这时“管理员”的第一反应是去翻“员工花名册”——也就是我们在META-INF/dubbo/或META-INF/dubbo/internal/目录下的配置文件。这个文件的名字就是接口的全限定名如org.apache.dubbo.rpc.cluster.LoadBalance内容是一行行的keyvalue例如randomorg.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance。ExtensionLoader会把这些配置加载到一个MapString, Class?里缓存起来。所以“按名称加载”的本质就是根据你传入的key如random从这个Map里找到对应的实现类的全限定名。这里有个我踩过的坑配置文件路径一定要对。上次我就在项目里自定义了一个Filter死活不生效调试了半天才发现我在IDEA里创建目录时手滑打成了META-INF.dubbo用点号分隔而IDEA的文件夹显示和正确的META-INF/dubbo看起来一模一样实际上前者创建的是一个包路径后者才是文件夹路径。所以务必在创建时选择“Directory”目录而不是“Package”包。2.3 第三步创造生命——实例化与依赖注入找到了实现类的全限定名接下来就是创建对象。Dubbo默认会通过反射调用无参构造器来实例化。但创建出对象并不是终点更重要的是依赖注入IoC。这是Dubbo SPI比Java原生SPI强大的一个关键点。假设你自定义的Filter实现类里需要通过一个setter方法注入另一个扩展点比如一个监控服务MonitorService。代码如下public class MyFilter implements Filter { private MonitorService monitorService; // 通过setter方法声明依赖 public void setMonitorService(MonitorService monitorService) { this.monitorService monitorService; } Override public Result invoke(Invoker? invoker, Invocation invocation) throws RpcException { monitorService.record(invocation); // 使用依赖的扩展点 return invoker.invoke(invocation); } }ExtensionLoader在实例化MyFilter后会扫描其所有setter方法。发现setMonitorService方法需要一个MonitorService类型的参数。这时它会递归地调用ExtensionLoader.getExtensionLoader(MonitorService.class).getAdaptiveExtension()去获取一个自适应的MonitorService实例通常是动态代理对象然后通过反射调用这个setter方法将monitorService注入进去。这个过程完全是自动的你不需要在代码里手动去new或者查找大大降低了组件间的耦合度。2.4 第四步武装升级——自动包装AOP依赖注入完成后对象是不是就可以直接返回了还差一步自动包装。这其实是Dubbo实现AOP面向切面编程的一种方式。我们去看Protocol的配置文件会发现除了dubbo,hessian这样的具体协议实现还有一个org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper。ExtensionLoader在创建完一个Protocol扩展点实例比如DubboProtocol后会检查缓存中是否存在“包装类”。包装类通常本身也是该接口的实现并且其构造方法接受一个该接口类型的参数。例如public class ProtocolFilterWrapper implements Protocol { private final Protocol protocol; public ProtocolFilterWrapper(Protocol protocol) { this.protocol protocol; } // ... 重写export和refer方法在方法前后加入过滤器链逻辑 }ExtensionLoader会找到所有这样的包装类然后像“俄罗斯套娃”一样一层层地将原始对象包装起来。最终返回给你的是最外层的包装类对象。当你调用这个对象的export方法时会先经过外层包装的逻辑比如构建过滤器链再调用内层核心对象的逻辑。这样我们就能在不修改核心类代码的情况下为扩展点动态添加额外的功能比如日志、监控、鉴权等这就是AOP的魅力。至此一个完整的、经过依赖注入和AOP包装的扩展点实例才被创建出来并返回给调用者。整个流程确保了扩展点不仅是可用的更是功能完整、与其他组件协同工作的。3. 智能选择自适应扩展点Adaptive的实现原理“按名称加载”需要我们显式地指定一个key。但在很多场景下我们希望在运行时根据条件自动选择最合适的扩展点。比如一个服务接口的URL是dubbo://...那就该用DubboProtocol如果是rest://...就该用RestProtocol。这就是自适应扩展点要解决的问题它通过Adaptive注解来实现。3.1 注解的两种用法与本质区别Adaptive注解可以标在类上也可以标在方法上两者的含义和效果天差地别。第一种标在类上。这表示这个类是一个“自适应扩展点的默认实现”。当调用getAdaptiveExtension()方法时会直接返回这个类的实例。这种类通常本身就是一个适配器或代理内部包含了选择逻辑。比如AdaptiveExtensionFactory它就是ExtensionFactory接口的一个自适应实现用于决定到底用SpiExtensionFactory还是SpringExtensionFactory去查找扩展点。第二种标在方法上。这才是“自适应扩展”的精髓所在。当Adaptive注解标在接口的方法上时ExtensionLoader不会返回任何一个具体的实现类实例而是会为这个接口动态生成一个代理类。我们以Protocol接口的refer方法为例SPI(dubbo) public interface Protocol { Adaptive T ExporterT export(InvokerT invoker) throws RpcException; Adaptive T InvokerT refer(ClassT type, URL url) throws RpcException; }ExtensionLoader会分析这个接口为它生成一个名为Protocol$Adaptive的类。这个类实现了Protocol接口并在refer方法里写入了动态选择的逻辑。生成的代码大致如下简化版public class Protocol$Adaptive implements Protocol { public T InvokerT refer(ClassT type, URL url) throws RpcException { if (url null) throw new IllegalArgumentException(url null); // 1. 从URL或Adaptive注解value值中获取协议名 String extName (url.getProtocol() null) ? dubbo : url.getProtocol(); if (extName null) throw new IllegalStateException(Failed to get extension name); // 2. 根据协议名使用ExtensionLoader按名称加载具体的Protocol实现 Protocol extension ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(extName); // 3. 委托给具体的实现类去执行真正的refer逻辑 return extension.refer(type, url); } // ... export方法类似 }这个动态生成的类就是我们在Dubbo代码中经常看到的“自适应扩展类”。它的核心逻辑就是从URL或注解参数中提取一个决定性的参数如protocol用这个参数的值作为key再去走“按名称加载”的流程。3.2 URL自适应机制的灵魂可以看到整个自适应选择的核心依据就是URL。Dubbo将URL作为配置信息的载体贯穿始终Adaptive注解的方法可以从传入的URL对象中提取参数。注解本身也可以指定参数名例如Adaptive(loadbalance)会从URL中取loadbalance参数的值作为扩展名。这种设计极其巧妙和灵活。在实际调用中我们可能根本看不到getExtension的调用。例如在服务引用时框架内部会调用Protocol$Adaptive.refer(interfaceClass, url)。这个url里已经包含了protocoldubbo等信息自适应类就能自动找到DubboProtocol并调用其refer方法。对于使用者来说这一切都是透明的我们只需要关心配置。3.3 实战看懂一个自适应扩展的生效过程让我们设想一个场景在服务消费者的配置中我们指定了loadbalanceleastactive最小活跃数负载均衡。这个配置最终会被添加到服务目录的URL中。当发起一次调用时集群容错层Cluster会获取一个LoadBalance的自适应实例LoadBalance$Adaptive。这个自适应实例的select方法被调用时它会从当前调用上下文的URL或Invocation附带的URL参数中取出loadbalance参数的值也就是leastactive。然后它调用ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(leastactive)加载出LeastActiveLoadBalance的实例并委托其执行真正的选择逻辑。整个过程对开发者来说是“配置即代码”。我们通过一个简单的配置项就驱动了整个扩展点加载和选择链条这正是Dubbo扩展机制设计的高明之处。4. 批量装配自动激活扩展点Activate的应用有些扩展点不是“单选”而是“多选”的最典型的就是Filter。一次RPC调用可能需要经过多个过滤器的处理比如监控、日志、鉴权、限流等。我们当然可以在每个服务引用或暴露时都显式配置一长串filter列表但这太麻烦了。Dubbo提供了自动激活扩展点机制通过Activate注解来实现“批量装配”。4.1 Activate注解的妙用Activate注解主要标在扩展点的实现类上用来声明该实现类在什么条件下应该被自动激活加入到扩展点集合中。它有几个关键属性group指定生效的组别。常见的有{Constants.PROVIDER, Constants.CONSUMER}。例如一个只在服务提供者端生效的过滤器可以标注Activate(group Constants.PROVIDER)。value指定触发条件。它是一个字符串数组表示当URL中包含这些指定的Key即使Value为空时该扩展点才被激活。例如Activate(value {token})表示当URL中有token参数时这个过滤器才生效。order排序值。当多个扩展点被激活时按order从小到大排序形成链式调用。4.2 加载与过滤逻辑当我们调用ExtensionLoader.getActivateExtension(URL url, String key, String group)方法时例如在构建过滤器链时ExtensionLoader会做以下几件事加载所有标有Activate的实现类从缓存中获取该接口所有实现类筛选出带有Activate注解的。按group过滤如果调用时指定了group如provider则只保留group属性中包含该组的实现类。按value过滤检查传入的URL如果实现类的value属性不为空则要求URL中必须包含这些Key该实现类才会被激活。处理用户自定义配置参数key通常对应URL中的某个配置键比如filter。框架会先读取URL中key对应的值如filtermyFilter,-validation。这个值可以添加新的过滤器myFilter也可以移除默认激活的过滤器-validation表示移除ValidationFilter。合并与排序将URL中显式配置的扩展点、通过Activate条件匹配的扩展点进行合并并剔除被“-”显式移除的。最后按照order属性和配置的先后顺序进行排序形成一个有序的列表返回。4.3 实战自定义一个自动激活的监控过滤器假设我们需要一个在服务提供者端自动激活的过滤器用于统计每个方法的调用次数。我们可以这样实现import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.rpc.*; import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER; Activate(group PROVIDER) // 仅Provider端自动激活 public class MonitorCountFilter implements Filter { // 假设有一个监控计数器 private CounterService counterService; // 可以通过setter注入其他扩展点 public void setCounterService(CounterService counterService) { this.counterService counterService; } Override public Result invoke(Invoker? invoker, Invocation invocation) throws RpcException { // 调用前计数 String methodName invocation.getMethodName(); counterService.increment(methodName); try { // 继续执行过滤器链 return invoker.invoke(invocation); } finally { // 调用后也许可以记录耗时等 } } }然后在META-INF/dubbo/org.apache.dubbo.rpc.Filter文件中配置monitorCountcom.yourcompany.MonitorCountFilter这样所有服务提供者启动时这个MonitorCountFilter都会被自动加入到过滤器链中无需在每个服务上单独配置。如果你想在某个特定服务上禁用这个过滤器只需要在该服务的提供者配置中加上filter-monitorCount即可。5. 实战进阶手把手打造自定义扩展点理解了原理最好的巩固方式就是动手实践。我们来完成一个稍微复杂点的实战自定义一个Router路由规则。Router决定了在众多服务提供者中本次调用应该选择哪一个我们可以用它来实现灰度发布、机房就近路由等高级功能。5.1 第一步定义扩展点接口与实现Dubbo已经定义了org.apache.dubbo.rpc.cluster.Router接口。我们通常不需要重新定义接口而是直接实现它。但我们这里为了演示从零开始假设我们要创建一个全新的扩展点TagRouter用于根据请求中的标签Tag选择对应标签的服务提供者。首先定义接口并标记为Dubbo扩展点import org.apache.dubbo.common.extension.SPI; SPI(default) // 指定默认实现名称为default public interface TagRouter { /** * 根据标签路由 * param providers 候选提供者列表 * param tag 请求携带的标签 * return 路由筛选后的提供者列表 */ ListInvoker? route(ListInvoker? providers, String tag); }接着我们实现两个版本// 默认实现无标签或标签匹配不上时返回所有提供者 public class DefaultTagRouter implements TagRouter { Override public ListInvoker? route(ListInvoker? providers, String tag) { if (tag null || tag.isEmpty()) { return providers; } // 简单演示筛选URL中带有相同tag参数的提供者 ListInvoker? result new ArrayList(); for (Invoker? invoker : providers) { URL url invoker.getUrl(); String providerTag url.getParameter(tag, ); if (tag.equals(providerTag)) { result.add(invoker); } } return result.isEmpty() ? providers : result; // 若无匹配降级返回全部 } } // 灰度发布实现只有部分比例的流量会路由到带标签的提供者 public class GrayReleaseTagRouter implements TagRouter { Override public ListInvoker? route(ListInvoker? providers, String tag) { // 模拟从配置中心读取灰度比例例如 0.1 表示10%流量 double grayRatio 0.1; Random random new Random(); if (random.nextDouble() grayRatio) { // 走灰度逻辑筛选带tag的提供者 return filterByTag(providers, tag); } else { // 走普通逻辑筛选不带tag的提供者或全部 return filterWithoutTag(providers, tag); } } // ... 省略具体的过滤方法 }5.2 第二步编写配置文件在项目的resources目录下创建文件META-INF/dubbo/com.yourcompany.TagRouter。 文件内容为defaultcom.yourcompany.router.DefaultTagRouter graycom.yourcompany.router.GrayReleaseTagRouter这样我们就注册了两个实现。5.3 第三步在代码中加载与使用现在我们可以在业务代码中像使用Dubbo内置扩展点一样使用我们的TagRouter。public class TagRouterService { // 1. 获取扩展点加载器 private static final ExtensionLoaderTagRouter loader ExtensionLoader.getExtensionLoader(TagRouter.class); // 2. 按需加载 private final TagRouter defaultRouter loader.getExtension(default); private final TagRouter grayRouter loader.getExtension(gray); public void invokeWithTag(ListInvoker? providers, String tag, boolean isGray) { TagRouter router isGray ? grayRouter : defaultRouter; ListInvoker? routedProviders router.route(providers, tag); // ... 使用 routedProviders 进行调用 } }或者我们也可以将其集成到Dubbo的调用链中这需要更深入的集成比如实现一个Cluster包装器在调用前先执行我们的标签路由逻辑。这涉及到对Dubbo核心调用流程的介入是更高级的用法。5.4 避坑指南与最佳实践在自定义扩展点的过程中我总结了一些经验和坑线程安全你的扩展点实现类必须是线程安全的。因为ExtensionLoader默认会缓存扩展点实例除非标注DisableInject同一个实现类通常只有一个单例对象被所有线程共享。不要在实现类中轻易使用可变的成员变量。谨慎使用依赖注入虽然依赖注入很方便但要避免循环依赖。A依赖BB又依赖A会导致初始化失败。配置文件命名再次强调配置文件必须放在正确的路径META-INF/dubbo/且文件名必须是接口的全限定名区分大小写。合理使用自适应与自动激活思考你的扩展点更适合哪种加载方式。如果是全局唯一的策略如协议考虑用Adaptive。如果是可叠加的处理器链如Filter、Router考虑用Activate。版本兼容在升级Dubbo版本时注意核心SPI接口可能会有变化。自定义扩展点前最好先查看目标版本的内置实现了解接口的契约。通过这样一个完整的自定义Router的例子你应该能深刻感受到Dubbo扩展机制的强大与灵活。它不仅仅是一个加载类工具更是一套完整的、支持IoC和AOP的微内核插件管理体系。掌握了它你就拥有了按需定制Dubbo框架的能力能够让它更好地适配你业务中那些独特而复杂的需求。

相关新闻

实战剖析原型链污染漏洞(CVE-2019-10744):从攻击链到防御策略

实战剖析原型链污染漏洞(CVE-2019-10744):从攻击链到防御策略

1. 从一次“诡异”的权限绕过说起 几年前,我在排查一个内部管理系统的安全问题时,遇到了一件怪事。系统日志显示,一个普通用户账号竟然成功访问了只有管理员才能进入的“后台用户管理”页面。我们反复检查了数据库里的用户角色字段&#xff0…

2026/7/6 13:42:10 阅读更多 →
从零推导到电路仿真:二阶压控电压源高通滤波器传递函数实战解析

从零推导到电路仿真:二阶压控电压源高通滤波器传递函数实战解析

1. 从“虚短虚断”开始:手把手推导传递函数 很多朋友一看到电路图里又是运放又是电容电阻,就觉得头大,公式更是像天书。别怕,今天咱们就从一个最经典的二阶压控电压源高通滤波器电路开始,我带着你,像解一道…

2026/7/5 13:55:56 阅读更多 →
FreeRTOS下Easylogger异步日志的缓冲区优化与性能调优

FreeRTOS下Easylogger异步日志的缓冲区优化与性能调优

1. 从日志丢失的“灵异事件”说起:为什么你的异步日志不灵了? 最近在调试一个基于FreeRTOS的嵌入式项目,用上了Easylogger的异步输出模式,本以为从此可以高枕无忧,让日志在后台默默输出,不打扰主任务的执行…

2026/7/4 11:03:12 阅读更多 →

最新新闻

date-io核心原理:为什么它能成为日期库的万能适配器?

date-io核心原理:为什么它能成为日期库的万能适配器?

date-io核心原理:为什么它能成为日期库的万能适配器? 【免费下载链接】date-io Abstraction over common javascript date management libraries 项目地址: https://gitcode.com/gh_mirrors/da/date-io date-io是一个针对JavaScript日期管理库的…

2026/7/6 18:05:50 阅读更多 →
如何在React中集成ArcGIS Maps SDK组件?完整实现指南与示例代码

如何在React中集成ArcGIS Maps SDK组件?完整实现指南与示例代码

如何在React中集成ArcGIS Maps SDK组件?完整实现指南与示例代码 【免费下载链接】jsapi-resources A collection of resources for developers using the ArcGIS Maps SDK for JavaScript. 项目地址: https://gitcode.com/gh_mirrors/js/jsapi-resources 想在…

2026/7/6 18:05:50 阅读更多 →
为什么你的draw.io桌面版Mermaid图表无法编辑?深度解析与修复指南

为什么你的draw.io桌面版Mermaid图表无法编辑?深度解析与修复指南

为什么你的draw.io桌面版Mermaid图表无法编辑?深度解析与修复指南 【免费下载链接】drawio-desktop Official electron build of draw.io 项目地址: https://gitcode.com/GitHub_Trending/dr/drawio-desktop 对于许多技术爱好者和普通用户来说,dr…

2026/7/6 18:03:49 阅读更多 →
Fabric Loader高级特性:Access Widener与Tiny Remapper详解

Fabric Loader高级特性:Access Widener与Tiny Remapper详解

Fabric Loader高级特性:Access Widener与Tiny Remapper详解 【免费下载链接】fabric-loader Fabrics mostly-version-independent mod loader. 项目地址: https://gitcode.com/gh_mirrors/fa/fabric-loader 在Minecraft模组开发领域,Fabric Loade…

2026/7/6 18:01:48 阅读更多 →
基于STM32单片机的智能窗户/窗帘晾衣架/雨滴光照检测系统成品32(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_

基于STM32单片机的智能窗户/窗帘晾衣架/雨滴光照检测系统成品32(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_

基于STM32单片机的智能窗户/窗帘晾衣架/雨滴光照检测系统成品32(设计源文件万字报告讲解)(支持资料、图片参考_相关定制)_ LCD1602液晶显示当前窗帘状态开启/关闭 显示当前模式手动/自动 手动模式:按下第二个按键电机反转表示直接打开 窗帘/晾…

2026/7/6 17:59:46 阅读更多 →
coredumpy部署指南:在CI/CD流水线中集成崩溃调试功能

coredumpy部署指南:在CI/CD流水线中集成崩溃调试功能

coredumpy部署指南:在CI/CD流水线中集成崩溃调试功能 【免费下载链接】coredumpy coredumpy saves your crash site for post-mortem debugging 项目地址: https://gitcode.com/gh_mirrors/co/coredumpy 在当今快速迭代的软件开发环境中,崩溃调试…

2026/7/6 17:59:46 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻