39.2. 实现组件接口
DefaultComponent 类
您可以通过扩展 org.apache.camel.impl.DefaultComponent
类来实施新组件,它为某些方法提供了一些标准功能和默认实现。特别是,DefaultComponent
类提供对 URI 解析和创建 调度的 executor (用于调度的轮询模式)的支持。
URI 解析
基础组件接口中定义的 createEndpoint (String uri)
方法使用完整的未解析端点 URI 作为其唯一参数。另一方面,DefaultComponent
类定义了 createEndpoint ()
方法的三参数版本,其签名如下:
protected abstract Endpoint createEndpoint( String uri, String remaining, Map parameters ) throws Exception;
URI 是原始的未解析 URI; 其余
是 URI 的一部分,它位于开始处的组件前缀后保留,并去掉末尾查询选项; 参数
包含解析的查询选项。这是从
DefaultComponent
继承时必须覆盖的 createEndpoint ()
方法的此版本。具有已为您解析端点 URI 的优点。
以下文件
组件的端点 URI 示例显示了 URI 解析在实践中的工作方式:
file:///tmp/messages/foo?delete=true&moveNamePostfix=.old
对于此 URI,以下参数会传递到 createEndpoint ()
的三参数版本:
参数 | 值示例 |
---|---|
| |
|
|
|
在
|
参数注入
默认情况下,从 URI 查询选项中提取的参数注入到端点的 bean 属性中。DefaultComponent
类会自动注入您的参数。
例如,如果要定义支持两个 URI 查询选项的自定义端点: delete
和 moveNamePostfix
。您必须做的是在端点类中定义对应的 bean 方法(getter 和 setters):
public class FileEndpoint extends ScheduledPollEndpoint { ... public boolean isDelete() { return delete; } public void setDelete(boolean delete) { this.delete = delete; } ... public String getMoveNamePostfix() { return moveNamePostfix; } public void setMoveNamePostfix(String moveNamePostfix) { this.moveNamePostfix = moveNamePostfix; } }
也可以将 URI 查询选项注入 消费者 参数。详情请查看 “消费者参数注入”一节。
禁用端点参数注入
如果您的 Endpoint
类中没有定义参数,您可以通过禁用端点参数注入来优化端点创建的过程。要禁用端点上的参数注入,请覆盖 useIntrospectionOnEndpoint ()
方法,并实施它来返回 false
,如下所示:
protected boolean useIntrospectionOnEndpoint() { return false; }
useIntrospectionOnEndpoint ()
方法不会影响在 Consumer
类上执行的参数注入。该级别的参数注入由 Endpoint.configureProperties ()
方法控制(请参阅 第 40.2 节 “实施端点接口”)。
调度的 executor 服务
调度的 executor 用于调度的轮询模式,其中负责驱动消费者端点的定期轮询(调度的 executor 实际上是一个线程池实现)。
要实例化调度的 executor 服务,请使用 CamelContext.get
对象。有关 Apache Camel 线程模型的详情,请参考 第 2.8 节 “线程模型”。
ExecutorServiceStrategy
方法返回的 ExecutorServiceStrategy
在 Apache Camel 2.3 之前,DefaultComponent
类提供了一个 getExecutorService ()
方法,用于创建线程池实例。但是,从 2.3 开始,创建线程池现在由 ExecutorServiceStrategy
对象集中管理。
验证 URI
如果要在创建端点实例前验证 URI,您可以覆盖 DefaultComponent
类中的 validateURI ()
方法,它有以下签名:
protected void validateURI(String uri, String path, Map parameters) throws ResolveEndpointFailedException;
如果提供的 URI 没有所需的格式,则 validateURI ()
的实现会抛出 org.apache.camel.ResolveEndpointFailedException
异常。
创建端点
例 39.2 “createEndpoint ()
的实现” 概述了如何实施 DefaultComponent.createEndpoint ()
方法,它负责按需创建端点实例。
例 39.2. createEndpoint ()
的实现
public class CustomComponent extends DefaultComponent { 1 ... protected Endpoint createEndpoint(String uri, String remaining, Map parameters) throws Exception { 2 CustomEndpoint result = new CustomEndpoint(uri, this); 3 // ... return result; } }
示例
例 39.3 “FileComponent 实现” 显示 FileComponent
类的示例实现。
例 39.3. FileComponent 实现
package org.apache.camel.component.file; import org.apache.camel.CamelContext; import org.apache.camel.Endpoint; import org.apache.camel.impl.DefaultComponent; import java.io.File; import java.util.Map; public class FileComponent extends DefaultComponent { public static final String HEADER_FILE_NAME = "org.apache.camel.file.name"; public FileComponent() { 1 } public FileComponent(CamelContext context) { 2 super(context); } protected Endpoint createEndpoint(String uri, String remaining, Map parameters) throws Exception { 3 File file = new File(remaining); FileEndpoint result = new FileEndpoint(file, uri, this); return result; } }
- 1
- 始终为组件类定义 no-argument 构造器,以便于实例化类。
- 2
- 在通过编程创建组件实例时,使用父
CamelContext
实例作为参数的构造器是方便的。 - 3
FileComponent.createEndpoint ()
方法的实现遵循 例 39.2 “createEndpoint ()
的实现” 中描述的模式。该实施会创建一个FileEndpoint
对象。
SynchronizationRouteAware Interface
SynchronizationRouteAware
接口允许您在交换路由之前和之后具有回调。
-
onBeforeRoute
:在由给定路由路由交换之前调用。但是,如果您在启动路由后将SynchronizationRouteAware
实现添加到UnitOfWork
,则可能无法调用此回调。 onAfterRoute
:在由给定路由路由交换后调用。但是,如果交换通过多个路由路由,它会为每个路由生成调用 backs。这个调用发生在这些回调前:
-
路由的消费者将任何响应写回到调用者(如果在
InOut
模式中) -
UnitOfWork
通过调用Synchronization.onComplete (org.apache.camel.Exchange)
或Synchronization.onFailure (org.apache.camel.Exchange)
来完成。
-
路由的消费者将任何响应写回到调用者(如果在