组件
组件
组件是 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。
Component DSL
Component DSL 是一个构建器 API,允许以类型安全的方式构造 Camel 组件,并将其直接注入 Camel Context,而无需通过构造函数进行初始化。
编写组件
这是一个高级主题,编写组件指南 中有更详细的描述。
在组件中使用 HeaderFilterStrategy
某些组件支持配置自定义的标头过滤策略。
这允许你实现 org.apache.camel.spi.HeaderFilterStrategy 接口,在通信过程中过滤掉不需要的标头,同时不会将其从 Exchange 中移除。
Camel 核心提供了默认的过滤策略实现 DefaultHeaderFilterStrategy,可以为其提供一个正则表达式模式或一组要过滤掉的标头名称。
另请参阅
- 所有 Camel 组件的列表
评论
登录后参与评论
KnowForge