(本周模块亮点由Seam JMS模块负责人John Ament撰写。 - Shane)
by John Ament
这是Seam模块亮点系列的第三篇文章,今天我要介绍Seam JMS。
Seam JMS是一组旨在简化JMS使用场景的组件。Seam JMS旨在填补JMS API和更简洁的消息中间件工作方式之间的差距。我们通过以下方式实现:
- 为JMS资源提供基本的注入能力。
- 提供一个用于发送和接收消息的干净API
- 提供一个易于使用的机制,将JMS消息的发送和接收映射到CDI事件的触发和观察。
本文的主要目标是深入探讨如何将JMS消息作为CDI事件来处理。最后,我将简要讨论一些未来的内容。有关如何开始项目的详细信息,请从参考指南开始。
要求
为了使用Seam JMS,您需要有一个JMSConnectionFactory绑定在JNDI位置/ConnectionFactory。此外,您还需要将seam-jms.jar库包含在您的项目中;以及对于seam-solder.jar的必需依赖项。如果您的项目在servlet容器中运行,强烈建议您将seam-servlet.jar库包含在您的应用程序中,这将向应用程序添加容器启动事件支持。
映射
事件映射是Seam JMS的核心功能。这使得您可以通过触发CDI事件并将JMS消息发送到目的地,反之亦然。Seam JMS允许您定义单向和双向事件,支持输入(应用程序的输入)以及输出(应用程序的输出)。当使用双向路由时,应用程序将创建并处理事件,作为一个异步事件处理。
路由
CDI事件与JMS消息的映射通过POJIs(普通Java接口)实现。有三种支持的方式通过接口创建路由。以下是一个快速映射接口的示例:
public interface ApplicationObserverMappings { @Routing(RouteType.BOTH) public void mapStrings(@Observes String s, @MyTopic Topic topic); @Routing(RouteType.INGRESS) public void mapInboundLongs(@Observes Long l, @MyQueue Queue queue); @Routing(RouteType.EGRESS) public void mapOutboundShorts(@Observes Short s, @MyOtherTopic Topic topic); }
这会创建三条路由:一条出站路由、一条入站路由和一条双向路由。对于每个入站和双向路由,您需要定义一个观察者方法来监听在适当目的地触发的事件。处理入站路由时,在应用程序启动时会创建一个JMS消息监听器。注意:如果您在应用程序中没有使用Seam Servlet,您需要在启动组件中注入一个org.jboss.seam.jms.bridge.RouteBuilder的引用,以触发所有监听器的初始化。
此时,所有主题和队列都会通过CDI Bean查找来解析。每个通过消息监听器接收到的正确类型的消息都将触发正确类型的所有观察者方法。在上面的示例中,您需要为与配对限定符匹配的队列/主题定义适当的生成器方法,例如
@Resource(“jms/MyTopic”) Topic topic; @Produces @MyTopic public Topic produceMyTopic() { return topic; }
对于每个出站事件,您会定义一个CDI事件(注入点)。通过这个事件发送一个对象将创建一个JMS消息。
触发事件
定义了您的路由后,您需要有一个事件或BeanManager来触发事件。例如,在您的代码中注入以下内容事件在您的业务逻辑中,触发以下内容
@Inject @Routing(RouteType.EGRESS) Event<String> xmlEvent;
此事件将被转发到由CDI组件类型
public void sendData(String data) { xmlEvent.fire(“<simple>”+data+”</simple”); }
Topic标识的主题,其限定符为@MyTopic。一个TextMessage将发布到,其中包含事件中的文本。如果事件是另一个对象,则会发布一个标识的主题,其限定符为ObjectMessage。同样,如果我们使用一个Queue,适当的消息将被发送到队列。处理事件
对于所有入站和双向路由,Seam JMS将为在定义在路由中的JMS目的地接收到的所有
消息创建事件。这些事件将由JMS目的地接收到的所有将发布到消息触发。在上述示例中,您需要为队列/主题定义适当的生成器方法,以匹配配对限定符,例如对于每个出站事件,您会定义一个CDI事件(注入点)。通过这个事件发送一个对象将创建一个JMS消息。
触发事件
@Routing(RouteType.BOTH) public void mapStrings(@Observes String s, @MyTopic Topic topic); public void handleInBoundText(@Observes @Routing(RouteType.INGRESS) String xmlString) { … } @Routing(RouteType.INGRESS) public void mapInboundLongs(@Observes Long l, @MyQueue Queue queue); public void handleInBoundLongs(@Observes @Routing(RouteType.INGRESS) Long someId) { … }
定义了您的路由后,您需要有一个
事件。同样,如果我们使用一个或BeanManager来触发事件。例如,在您的代码中注入以下内容将发布到在您的业务逻辑中,触发以下内容。同样,如果我们使用一个此事件将被转发到由CDI组件类型Topic标识的主题,其限定符为
@MyTopic
。一个