Intercept作为一个极其强大的扩展机制,其理念几乎存在于所有知名框架中,诸如Spring,Mybatis,Tomcat等等都无一例外地提供了相应的支持,在保持自身框架本身整洁的同时,实现对各类业务场景的支持。而我们的Apache Camel也毫不意外地也提供了自己的Intercept实现,本文我们将尝试对Apache Camel的支持方式和实现逻辑进行一次探究,以期做到熟练运用。

1. 概述

Apache Camel中作为EIP实现者,诸如"当xxxx的时候,系统需要yyyy"的场景应该是属于常规需求了。Apache Camel提供了多种方式来完成对其的支持,本文将注意力集中到其中的一种实现方式 —— Intercept。

2. 源码解读

首先依然是本次的测试用例:

CamelTestUtil.defaultPrepareTest2(new RouteBuilder() {@Overridepublic void configure() throws Exception {                                       intercept().process(new Processor() {@Overridepublic void process(Exchange exchange) throws Exception {Console.error("intercept - " + exchange.getIn().getBody());}}).id("interceptProcess");// EmptyProcessor为一个空的Processor实现, 里面不作任何操作from("stream:in?promptMessage=Enter something:")//// 这里intercept输出 键入的内容.setBody(constant("1")).id("setBody-1")//// 这里intercept输出 上面的1.process(EmptyProcessor.me).id("EmptyProcessor1")//// 这里intercept输出 上面的1.setBody(constant("2")).id("setBody-2")//// 这里intercept输出 上面的2 .process(EmptyProcessor.me).id("EmptyProcessor2")//// 这里intercept输出 上面的2 .to("stream:err") // 这里输出红色的2// 这里输出 上面的2 .process(CamelLogRecordProcessor.me).id("logProcessor");}});
}

本次的源码解读按照之前的博客格式,依然是分为两部分:

2.1 启动时

首先让我们来看看在初始化阶段,Apache Camel是如何将Intercept功能组装进Camel执行链条中的。

以上用例启动之后,有以下两个比较重要的堆栈信息:

堆栈一(准备intercept实现者InterceptDefinition):

  1. 以上截图自RouteDefinitionHelper工具类,笔者特意将注释部分进行了保留,从中我们可以得知Apache Camel通过将 InterceptDefinition实例作为output集合中的第一个,实现了在intercept优先于actual route进行处理。这样就可以实现拦截所有node的目标。
  2. 图中字段intercept字段指向的实际类型正是InterceptDefinition

堆栈二(装配Intercept功能):

以上截图中:

  1. output字段指向的是测试用例配置的intercept()后配置的匿名Processor接口实现类。
  2. interceptedTarget字段指向的则是本次Route定义中的node,笔者本次截图是在第一次命中断点时候,因此这个node就是setBody()
  3. 上图中断点命中的位置可以看到 —— 作为拦截逻辑的匿名Processor实现和Route定义节点setBody()被封装为了一个Pipeline实例(注意两者的先后顺序,这关系到之后的执行顺序)。
  4. 在本次测试用例中,以上截图中的断点我们将命中六次,这正好对应测试用例中定义的node数量。
  5. 跳转到以上堆栈图中的DefaultChannel.initChannel()中,我们就会发现intercept()的实现是依赖于接口InterceptStrategy提供的扩展功能的。这一点从InterceptDefinition类间接继承自ProcessorDefinition,而其对于createProcessor方法的实现中就可见端倪。
2.2 执行时

在控制台敲入任意字符,我们将得到如下堆栈:

结合之前的系列博文,加之上一小节的初始化逻辑解析,我们可以很容易地解读出以上堆栈中表述的逻辑。

输入任意字符,我们将得到以下输出结果(结合上面的测试用例中的注释一起理解):

3. 扩展

其它诸如intercept()后接when()来进行条件拦截,或者interceptFrom()interceptSendToEndpoint(),限于篇幅原因本次就不再详述了,读者感兴趣的可以自行阅读相关源码或者下方给出的官方链接。

4. 总结

  1. 对应intercept(),Apache Camel内部使用InterceptDefinition类来统筹整个配置组装初始化的工作。而具体的实现逻辑则依赖于接口InterceptStrategy提供的扩展功能。这一点可以从InterceptDefinition类间接继承自ProcessorDefinition,而其对于createProcessor方法的实现中就可见端倪。
  2. 对应intercept(),其执行时机位于匹配node执行之前。正如上面解析的,Apache Camel使用Pipeline来将intercept功能和用户自定义node组装在一起,确保每个node拦截逻辑的独立性。

5. Links

  1. Office Site - Intercept
  2. Apache Camel源码研究之InterceptStrategy
  3. Apache Camel源码研究之ProcessorDefinition
  4. 《Camel In Action》 P178, 288, P377

Apache Camel源码研究之Intercept相关推荐

  1. Apache Camel源码研究之Rest

    本文以Camel2.24.3 + SpringBoot2.x 为基础简单解读Camel中的Rest组件的源码级实现逻辑. 0. 目录 1. 前言 2. 源码解读 2.1 启动时 2.1.1 `Rest ...

  2. Apache Camel源码研究之Language

    Apache Camel通过Language将Expression和Predicate的构造操作合并在一起,减少了概念,也降低了扩展难度,是的整体架构更加清晰. 1. 概述 Apache Camel为 ...

  3. Apache Jackrabbit源码研究(五)

    上文最后提到jackrabbit的检索默认实现类QueryImpl,先熟悉一下该类的继承层次 QueryImpl继承自抽象类AbstractQueryImpl,而抽象类实现了Query接口(JCR的接 ...

  4. Apache Tika源码研究(七)

    tika怎样加载Parser实现类的,怎样根据文档的mime类型调用相应的Parser实现类,本文接着分析 先熟悉一下tika的解析类的相关接口和类的UML模型: Parser接口的源码如下: /** ...

  5. WebRTC源码研究(4)web服务器工作原理和常用协议基础

    文章目录 WebRTC源码研究(4)web服务器工作原理和常用协议基础 前言 做WebRTC 开发为啥要懂服务器开发知识 1. Web 服务器简介 2. Web 服务器的类型 3. Web 服务器的工 ...

  6. WebRTC源码研究(4)web服务器工作原理和常用协议基础(转载)

    前言 前面3篇博客分别对WebRTC框架的介绍,WebRTC源码目录,WebRTC的运行机制进行了介绍,接下来讲解一点关于服务器原理的知识.后面博客会写关于WebRTC服务器相关的开发,目前git上面 ...

  7. 一起谈.NET技术,.NET Framework源码研究系列之---万法归宗Object

    经过前面三篇关于.NET Framework源码研究系列的随笔,相信大家都发现其实.NET Framework的实现其实并不复杂,也许跟我们自己做的项目开发差不多.本人也是这样的看法.不过,经过仔细深 ...

  8. Nginx源码研究之nginx限流模块详解

    这篇文章主要介绍了Nginx源码研究之nginx限流模块详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 高并发系统有三把利器:缓存.降级和限流: 限流的目的是通过对并 ...

  9. 转载一篇《Redis源码研究—哈希表》重点是如何重新哈希

    <Redis源码研究-哈希表>来自:董的博客 网址:http://dongxicheng.org/nosql/redis-code-hashtable/ 转载于:https://www.c ...

最新文章

  1. 如何将java web项目上线/部署到公网
  2. Unity3d简单的socket通信
  3. 广度优先搜索算法BFS讲解以及python 实现
  4. git lfs的安装和使用详细案例
  5. 关于SAP Fiori Smart Template开发的一些实际例子
  6. db2 创建样本数据库_db2创建数据库
  7. Linux 内核调试器 调试指南
  8. hadoop2.2.0 分布式存储hdfs完全分布式搭建及功能测试记录(一)----架构及原理介绍...
  9. android关闭系统弹窗,Android 禁止 EditText 弹出软件盘
  10. C语言指针概念全面解析
  11. IM即时通讯源码系统安卓苹果IOS双端源码介绍
  12. 中国电科发布新型智慧城市顶层设计
  13. promise执行顺序总结
  14. 双硬盘win10下安装ubuntu的方法
  15. bmi计算器公式_bmi计算器公式
  16. ISO、快门、光圈、曝光
  17. 在eclipse中使用subclipse
  18. 设计模式的六大原则(SOLID)
  19. badminton ball
  20. 2016年度最受欢迎中国开源软件评选 - 开源中国社区

热门文章

  1. 大厂历年的网络安全面试真题总结(附答案)
  2. Redis Cluster节点服务器宕机后导致集群重启失败案例
  3. omnigraffle 导出html,Omnigraffle如何输出文件教程
  4. C语言樱花树代码来喽~
  5. CCNA lab 随身日记之OSPF
  6. 【PhotoShop】三大图层样式运用介绍
  7. 微信小程序之仿微信漂流瓶
  8. Jiecaovideoplayer开始播放闪屏问题处理
  9. HTTP status code is not handled or not allowed的解决方法
  10. LPC2368FBD100芯片相关资料!