60.10. CDI 事件端点
从 Camel 2.17 开始提供
CDI 事件端点通过 Camel 路由 桥接 CDI 事件,以便可以从 Camel 用户(由 Camel 生成者resp.)无缝观察到被使用的/消耗(由 Camel 生成者生成 / fired)。
Camel CDI 提供的 CdiEventEndpoint<T
> bean 可用于观察 / 使用 事件类型 为 T
的 CDI 事件,例如:
@Inject CdiEventEndpoint<String> cdiEventEndpoint; from(cdiEventEndpoint).log("CDI event received: ${body}");
这等同于编写:
@Inject @Uri("direct:event") ProducerTemplate producer; void observeCdiEvents(@Observes String event) { producer.sendBody(event); } from("direct:event").log("CDI event received: ${body}");
相反,CdiEventEndpoint<T
> bean 可以用来生成 / 触发 事件类型 为 T
的 CDI 事件,例如:
@Inject CdiEventEndpoint<String> cdiEventEndpoint; from("direct:event").to(cdiEventEndpoint).log("CDI event sent: ${body}");
这等同于编写:
@Inject Event<String> event; from("direct:event").process(new Processor() { @Override public void process(Exchange exchange) { event.fire(exchange.getBody(String.class)); } }).log("CDI event sent: ${body}");
或使用 Java 8 lambda 表达式:
@Inject Event<String> event; from("direct:event") .process(exchange -> event.fire(exchange.getIn().getBody(String.class))) .log("CDI event sent: ${body}");
特定 CdiEventEndpoint<
(resp. 到 事件限定符)例如:
T
> 注入点的 type 变量 T (代表限定符)会自动转换为参数化事件类型
@Inject @FooQualifier CdiEventEndpoint<List<String>> cdiEventEndpoint; from("direct:event").to(cdiEventEndpoint); void observeCdiEvents(@Observes @FooQualifier List<String> event) { logger.info("CDI event: {}", event); }
当 CDI 容器中存在多个 Camel 上下文时,Camel 上下文 bean 限定符(如 @ContextName
)可用于验证 CdiEventEndpoint<T&
gt; 注入点,例如:
@Inject @ContextName("foo") CdiEventEndpoint<List<String>> cdiEventEndpoint; // Only observes / consumes events having the @ContextName("foo") qualifier from(cdiEventEndpoint).log("Camel context (foo) > CDI event received: ${body}"); // Produces / fires events with the @ContextName("foo") qualifier from("...").to(cdiEventEndpoint); void observeCdiEvents(@Observes @ContextName("foo") List<String> event) { logger.info("Camel context (foo) > CDI event: {}", event); }
请注意,CDI 事件 Camel 端点会动态地为 事件类型 和事件 限定符 组合添加 观察方法 ,并且只依赖于容器类型safe observer 解析,这会导致尽可能有效地实施。
此外,作为 CDI 类型安全 性质和 Camel 组件 模型的动态性质之间的缺陷非常高,因此无法通过 URI 创建 CDI 事件 Camel 端点的实例。 实际上,CDI 事件组件的 URI 格式为:
cdi-event://PayloadType<T1,...,Tn>[?qualifiers=QualifierType1[,...[,QualifierTypeN]...]]
使用授权 PayloadType
(resp. the QualifierType
)是 URI 转义有效负载(resp. qualifier) raw 类型,后跟一个 type 参数部分来表示 payload 参数ized 类型。这会导致 不友好的 URI,例如:
cdi-event://org.apache.camel.cdi.example.EventPayload%3Cjava.lang.Integer%3E?qualifiers=org.apache.camel.cdi.example.FooQualifier%2Corg.apache.camel.cdi.example.BarQualifier
但是,从根本上讲,这会防止端点实例和观察器方法之间有效绑定,因为 CDI 容器在部署阶段没有发现 Camel 上下文模型的方法。