架构

组件

师成师成· 更新于 2026-09-28· 阅读 14 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

组件

组件是 Apache Camel 的基本构件,用于将路由连接到各种外部系统和服务。Camel 内置了大量组件,可提供对 HTTP、JMS、文件等众多技术和协议的连接支持。如果内置组件无法满足需求,你还可以创建自定义组件。

组件:基础知识

组件本质上是 Endpoint 实例的工厂。通常,应用程序不需要直接与组件交互。但在某些情况下,操作组件可能会对应用程序的性能、运行或扩展性带来好处。此时,这些应用程序可以通过 context 获取需要操作的端点实例,具体可使用方法 CamelContext.getEndpoint()。该方法会返回与所请求组件相对应的 Component 接口实现。例如,考虑以下代码:

myCamelContext.getEndpoint("pop3://john.smith@mailserv.example.com?password=myPassword");

对于上面示例中的 URI,CamelContext 对象会将 pop3 前缀映射到 MailComponent 类的实例。

getEndpoint() 的参数是一个 URI。URI 的 scheme(即 : 之前的部分)指定了组件的名称。在内部,CamelContext 对象维护着从组件名称到 Component 对象的映射。

配置组件选项

Camel 组件在两个不同的层次上进行配置:

  • 组件层次
  • 端点层次

组件层次是最高层次,保存着通用的、公共的配置,这些配置会被端点继承。例如,一个组件可能有安全设置、用于身份认证的凭据、网络连接的 URL 等。

有些组件只有少数几个选项,而另一些组件可能有很多选项。由于组件通常带有常用的预配置默认值,因此你往往只需要配置组件的少数几个选项,甚至完全不需要配置。

配置组件可以通过 Component DSL、配置文件(application.properties|yaml)或直接使用 Java 代码来完成。

配置端点选项

通常,你需要配置的是端点,因为端点往往有很多选项,可以让你配置端点所需的行为。这些端点选项也根据端点的类型进行分类:

  • 消费者(from)
  • 生产者(to)
  • 或两者兼有。

配置端点最常见的方式是直接在端点 URI 中以路径参数和查询参数的形式编写。你也可以使用 Endpoint DSL,以类型安全的方式来配置端点。

配置选项时的一个良好实践是使用属性占位符,它可以让我们避免在代码中硬编码 URL、端口号、敏感信息及其他设置。换句话说,使用占位符可以将配置从代码中外部化,从而获得更大的灵活性和可复用性。

Camel 如何将名称映射到组件

在入门指南中,我们解释了 Camel 维护着一个名称到组件的映射。这就引出了一个问题:Camel 如何用具名的 Component 对象填充这个映射。

通常,应用程序开发者无需关心这一点。但是,如果你正在编写自定义组件,这些信息则是基础。

填充该映射有两种方式:

  • 通过编程方式,使用 context
  • 通过延迟初始化

以编程方式注册

编程方式是指由应用层代码调用 CamelContext.addComponent(String componentName, Component component)。

下面的示例展示了同一个 MailComponent 对象以 3 个不同的名称注册到映射中。

Component mailComponent = new org.apache.camel.component.mail.MailComponent();
myCamelContext.addComponent("pop3", mailComponent);
myCamelContext.addComponent("imap", mailComponent);
myCamelContext.addComponent("smtp", mailComponent);

延迟初始化

在 CamelContext 对象中填充具名 Component 对象映射的第二种(也是更推荐的)方式,是让 CamelContext 对象执行延迟初始化。

这种方法依赖于开发者在编写实现 Component 接口的类时遵循一种约定。例如,假设你编写了一个名为 com.example.myproject.FooComponent 的类,并希望 Camel 能通过名称 foo 自动识别它。为此,你需要编写一个名为 META-INF/services/org/apache/camel/component/foo(不带 .properties 文件扩展名)的属性文件,其中包含一个名为 class 的条目,其值为你的类的完全限定名。例如:

META-INF/services/org/apache/camel/component/foo

class=com.example.myproject.FooComponent

如果你想让 Camel 也能通过 bar 这个名称识别该类,那么就在同一目录下编写另一个名为 bar 的属性文件,其内容与前者相同。编写好属性文件后,创建一个 JAR 文件,其中包含 com.example.myproject.FooComponent 类和这些属性文件,然后将该 JAR 文件加入到 CLASSPATH 中。这样,当应用层代码在 CamelContext 对象上调用 createEndpoint("foo:…​") 时,Camel 就会在 CLASSPATH 中找到 foo 属性文件,从该属性文件中读取 class 属性的值,并使用反射 API 创建指定类的实例。

Camel 开箱即用地支持各种通信技术。这些支持由实现了 Component 接口的类以及属性文件组成,属性文件使得 CamelContext 对象能够填充其具名 Component 对象的映射。

在本指南的前文中,我们给出了以下调用 CamelContext.getEndpoint() 的示例:

myCamelContext.getEndpoint("pop3://john.smith@mailserv.example.com?password=myPassword");

我们最初把该参数称为 URI,是因为在线的 Camel 文档和 Camel 源代码都声称这个参数是一个 URI。但实际上,该参数被限定为 URL。这是因为在 Camel 从参数中提取组件名时,它只查找第一个“:”,这是一种过于简单的算法。

请记住,在《Camel 入门》中我们解释过,URI 可以是 URL,也可以是 URN。

现在来看对 getEndpoint 的以下几次调用:

myCamelContext.getEndpoint("pop3:...");
myCamelContext.getEndpoint("jms:...");
myCamelContext.getEndpoint("urn:foo:...");
myCamelContext.getEndpoint("urn:bar:...");

Camel 会将上述示例中的组件识别为 pop3、jms、urn 和 urn。如果将后面的两个组件识别为 urn:foo 和 urn:bar,或者识别为 foo 和 bar(即跳过 urn: 前缀),会更加实用。因此,实践中必须使用 URL(形如 <scheme>:…​ 的字符串)而不是 URN(形如 urn:<scheme>:…​ 的字符串)来标识端点。由于缺乏对 URN 的适当支持,应当将方法 getEndpoint() 的参数视为 URL,而不是(正如其声称的)URI。

请务必阅读 端点以了解更多配置端点的信息。例如,如何引用 Registry 中的 bean、如何为密码选项使用原始值,以及如何使用属性占位符等。

Component DSL

Component DSL 是一个构建器 API,允许以类型安全的方式构造 Camel 组件,并将其直接注入 Camel Context,而无需通过构造函数进行初始化。

编写组件

这是一个高级主题,编写组件指南 中有更详细的描述。

在组件中使用 HeaderFilterStrategy

某些组件支持配置自定义的标头过滤策略。

这允许你实现 org.apache.camel.spi.HeaderFilterStrategy 接口,在通信过程中过滤掉不需要的标头,同时不会将其从 Exchange 中移除。

Camel 核心提供了默认的过滤策略实现 DefaultHeaderFilterStrategy,可以为其提供一个正则表达式模式或一组要过滤掉的标头名称。

另请参阅

  • 所有 Camel 组件的列表

评论

登录后参与评论

正在加载评论…