ServiceMix Bean组件提供了JBI总线与bean(POJO)的集成,这使得易于使用POJO来处理JBI消息交换。类似于在J2EE中的消息驱动Bean,一个POJO将从NMR接收消息,并可以以任何方式处理消息。不像JMS组件中的编码已经完成了,Bean组件给予了开发者可以创建任何类型的消息的自由,但是这必须是要手动编码的。
POJOs
有若干种POJO可用来部署到servicemix-bean。
MessageExchangeListener
这是第一种可部署的POJO类型,它实现了MessageExchangeListener接口。在这种情况下,servicemix-bean作为轻量级容器组件的替代物。这个层次提供了对接收到的和发送的交换的绝大部分控制。通常会使用注入的DeliveryChannel来回送交换。
这些POJO是低层次的POJO。你需要理解JBI API和消息交换模式以求能正确处理进入的交换。
Trace example
import org.apache.servicemix.MessageExchangeListener;
import javax.annotation.Resource;
import javax.jbi.messaging.DeliveryChannel;
import javax.jbi.messaging.ExchangeStatus;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.MessagingException;
public class ListenerBean implements MessageExchangeListener {
@Resource
private DeliveryChannel channel;
public void onMessageExchange(MessageExchange exchange) throws MessagingException {
System.out.println("Received exchange: " + exchange);
exchange.setStatus(ExchangeStatus.DONE);
channel.send(exchange);
}
}
Message processing example
import org.apache.servicemix.MessageExchangeListener;
import org.apache.servicemix.jbi.util.MessageUtil;
import org.apache.servicemix.jbi.jaxp.SourceTransformer;
import javax.annotation.Resource;
import javax.jbi.messaging.DeliveryChannel;
import javax.jbi.messaging.ExchangeStatus;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.MessagingException;
import javax.jbi.messaging.NormalizedMessage;
import javax.xml.transform.Source;
public class ListenerBean implements MessageExchangeListener {
@Resource
private DeliveryChannel channel;
public void onMessageExchange(MessageExchange exchange) throws MessagingException {
if (exchange.getStatus() == ExchangeStatus.ACTIVE) {
NormalizedMessage message = exchange.getMessage("in");
Source content = message.getContent();
//process content according to your logic
//e.g. to access the message body as a String use
String body = (new SourceTransformer()).toString(content);
message.setContent(content);
exchange.setMessage(message, "out");
channel.send(exchange);
}
}
}
部署
目前版本(v 3.1)的servicemix-bean支持两种不同的部署模型。第一种是使用xbean.xml配置文件。另一种是与静态配置文件servicemix.xml一起作用,但不能与标准JBI封装一起使用。
xbean.xml
<beans xmlns:bean="http://servicemix.apache.org/bean/1.0">
<bean:endpoint service="test:service" endpoint="endpoint" bean="#listenerBean"/>
<bean id="listenerBean" class="org.apache.servicemix.bean.beans.ListenerBean"/>
</beans>
Static configuration
<beans xmlns:sm="http://servicemix.apache.org/config/1.0"
xmlns:bean="http://servicemix.apache.org/bean/1.0"
xmlns:test="urn:test">
<sm:container id="jbi" embedded="true" createMBeanServer="false">
<sm:activationSpecs>
<sm:activationSpec>
<sm:component>
<bean:component/>
</sm:component>
</sm:activationSpec>
</sm:activationSpecs>
</sm:container>
<bean id="consumerBean" class="org.apache.servicemix.bean.beans.ConsumerBean"/>
<bean id="listenerBean" class="org.apache.servicemix.bean.beans.ListenerBean"/>
<bean id="annotatedBean" class="org.apache.servicemix.bean.beans.AnnotatedBean"/>
<bean id="plainBean" class="org.apache.servicemix.bean.beans.PlainBean"/>
</beans>
这些bean可以通过解析一个URI获取
DocumentFragment epr = URIResolver.createWSAEPR("bean:annotatedBean");
ServiceEndpoint se = client.getContext().resolveEndpointReference(epr);
exchange.setEndpoint(se);
Bean也可以通过搜索一个定义的包被发现
<beans xmlns:sm="http://servicemix.apache.org/config/1.0"
xmlns:bean="http://servicemix.apache.org/bean/1.0"
xmlns:test="urn:test">
<sm:container id="jbi" embedded="true" createMBeanServer="false">
<sm:activationSpecs>
<sm:activationSpec>
<sm:component>
<bean:component searchPackages="org.apache.servicemix.bean.beans"/>
</sm:component>
</sm:activationSpec>
</sm:activationSpecs>
</sm:container>
</beans>
在这种情况下,bean必须要有@Endpoint注释。
当然,也可以使用endpoint xml元素来配置POJO。
<beans xmlns:sm="http://servicemix.apache.org/config/1.0"
xmlns:bean="http://servicemix.apache.org/bean/1.0"
xmlns:test="urn:test">
<sm:container id="jbi" embedded="true" createMBeanServer="false">
<sm:activationSpecs>
<sm:activationSpec>
<sm:component>
<bean:component>
<bean:endpoints>
<bean:endpoint service="test:service" endpoint="endpoint" bean="#listenerBean"/>
</bean:endpoints>
</bean:component>
</sm:component>
</sm:activationSpec>
</sm:activationSpecs>
</sm:container>
<bean id="listenerBean" class="org.apache.servicemix.bean.beans.ListenerBean"/>
</beans>