46.4. 编程模型
概述
在 API 组件框架的上下文中,主要组件实施类派生自 org.apache.camel.util.component
软件包中的基础类。这些基础类定义在实施组件时可以(可选)覆盖的一些方法。在本节中,我们提供了对这些方法的简单描述,以及如何在自己的组件实施中使用它们。
来实现的组件方法
除了生成的方法实施(通常不需要修改),您也可以选择覆盖 组件
类中的以下方法:
doStart()
-
(可选) 在冷启动期间为组件创建资源的回调。另一种方法是采用 lazy 初始化 策略(仅在需要资源时重新分配资源)。实际上,Lazy 初始化通常是最佳策略,因此经常不需要
doStart
方法。 doStop()
(可选) 在组件停止时调用代码的回调。停止组件意味着其所有资源都关闭,内部状态会被删除,缓存会被清除,以此类推。
注意当当前的 CamelContext 关闭时,即使没有调用对应的
doStart
,Camel 保证在当前CamelContext
关闭时始终会调用doStop
。doShutdown
-
(可选) 在
CamelContext
关闭时调用代码的回调。停止的组件可以重新启动(带有冷启动语义),一个被完全关闭的组件。因此,这个回调代表最后一次释放属于组件的资源的几率。
在组件类中实施哪些其他事项?
组件
类是存放对组件对象本身具有相同(或类似)生命周期的对象的引用。例如,如果组件使用 OAuth 安全性,在组件类中保留对所需 OAuth 对象的引用,并在 组件
类中定义用于创建 OAuth 对象的方法。
执行的端点方法
您可以修改一些生成的方法,并选择性地覆盖 Endpoint
类中的一些继承方法,如下所示:
afterConfigureProperties()
此方法中需要执行的主要操作是创建适当类型的代理类(API 类),以匹配 API 名称。API 名称(已从端点 URI 提取)可通过继承的
apiName
字段或通过getApiName
访问器获得。通常,您要对apiName
字段执行交换机来创建对应的代理类。例如:// Java private Object apiProxy; ... @Override protected void afterConfigureProperties() { // TODO create API proxy, set connection properties, etc. switch (apiName) { case HELLO_FILE: apiProxy = new ExampleFileHello(); break; case HELLO_JAVADOC: apiProxy = new ExampleJavadocHello(); break; default: throw new IllegalArgumentException("Invalid API name " + apiName); } }
getApiProxy(ApiMethod 方法, Map<String, Object> args)
覆盖此方法,返回您在
ConfigureProperties 后创建的代理
实例。例如:@Override public Object getApiProxy(ApiMethod method, Map<String, Object> args) { return apiProxy; }
特殊情况下,您可能想要选择取决于 API 方法和参数的代理。对于需要,
getApiProxy
为您提供了使用此方法的灵活性。doStart()
-
(可选) 在冷启动过程中创建资源的回调。具有与
Component.doStart()
相同的语义。 doStop()
-
(可选) 在组件停止时调用代码的回调。具有与
Component.doStop()
相同的语义。 doShutdown
-
(可选) 在关闭组件时调用代码的回调。具有与
Component.doShutdown()
相同的语义。 interceptPropertyNames(Set<String> propertyNames)
(可选) API 组件框架使用端点 URI 和提供的选项值来确定调用的方法(可能源自于过载和别名)。如果组件在内部添加了选项或方法参数,但框架可能需要帮助来确定调用的正确方法。在这种情况下,您必须覆盖
interceptPropertyNames
方法,并为 set 的propertyNames
添加 extra(hidden 或 implicit)选项。当设置了propertyNames
中的完整方法参数列表时,框架将能够识别要调用的正确方法。注意您可以在
Endpoint
、Producer
或Consumer
类的级别上覆盖此方法。如果某个选项影响了制作者端点和消费者端点,则基本规则会覆盖Endpoint
类中的方法。interceptProperties(Map<String,Object> properties)
(可选) 通过覆盖此方法,您可以在调用 API 方法前修改或设置选项的实际值。例如,如果需要,您可以使用此方法为某些选项设置默认值。在实践中,通常需要覆盖
intercept
方法和 interceptProperty 方法。Property
Names注意您可以在
Endpoint
、Producer
或Consumer
类的级别上覆盖此方法。如果某个选项影响了制作者端点和消费者端点,则基本规则会覆盖Endpoint
类中的方法。
消费者方法实施
您可以选择在 Consumer
类中覆盖一些继承的方法,如下所示:
interceptPropertyNames(Set<String> propertyNames)
-
(可选) 此方法的语义与
Endpoint.interceptPropertyNames
类似 interceptProperties(Map<String,Object> properties)
-
(可选) 此方法的语义类似于
Endpoint.interceptProperties
doInvokeMethod(Map<String, Object> args)
(可选) 使用此方法可以截获 Java API 方法的调用。覆盖此方法的最常见原因是自定义方法调用的错误处理。例如,以下代码片段中显示了覆盖
doInvokeMethod
的典型方法:// Java @Override protected Object doInvokeMethod(Map<String, Object> args) { try { return super.doInvokeMethod(args); } catch (RuntimeCamelException e) { // TODO - Insert custom error handling here! ... } }
在本次实施中的某个时刻,您应该调用
doInvokeMethod
,以确保调用 Java API 方法。拦截器Result(Object methodResult, Exchange resultExchange)
-
(可选) 对 API 方法调用的结果进行一些额外的处理。例如,您可以在 Camel Exchange 对象(
resultExchange
)中添加自定义标头。 对象分割结果(Object 结果)
(可选) 默认情况下,如果方法 API 调用的结果是
java.util.Collection
对象或 Java 数组,API 组件框架会将结果拆分为 多个 交换对象(因此单个调用结果转换为多个消息)。如果要更改默认行为,您可以覆盖消费者端点中的
splitResult
方法。result
参数包含 API 消息调用的结果。如果要分割结果,您应该返回数组类型。注意您还可以通过在端点 URI 中设置
consumer.splitResult=false
来关闭默认分割。
实现生产者方法
您可以选择在 Producer
类中覆盖一些继承的方法,如下所示:
interceptPropertyNames(Set<String> propertyNames)
-
(可选) 此方法的语义与
Endpoint.interceptPropertyNames
类似 interceptProperties(Map<String,Object> properties)
-
(可选) 此方法的语义类似于
Endpoint.interceptProperties
doInvokeMethod(Map<String, Object> args)
-
(可选) 此方法的语义与
Consumer.doInvokeMethod
类似。 拦截器Result(Object methodResult, Exchange resultExchange)
-
(可选) 此方法的语义与
Consumer.interceptResult
类似。
Producer.splitResult()
方法 不会被 调用,因此无法分割 API 方法,从而造成与消费者端点相同的方式。若要获得制作者端点的类似效果,您可以使用 Camel 的 split()
DSL 命令(标准企业级集成模式之一)来分割 集合
或数组结果。
消费者轮询和线程模型
API 组件框架中消费者端点的默认线程模型 会被调度来轮询消费者。这意味着,消费者端点中的 API 方法会定期调用调度的时间间隔。如需了解更多详细信息,请参阅 “计划轮询消费者实施”一节。