ServiceMix provides support for JBI POJOs in addition to the usual JBI Components. JBI Components are maybe not as lightweight as they could be; there's a bunch of methods on there for dealing with metadata, management and capabilities along with a lifecycle object.
ServiceMix introduces the idea of a JBI POJO which is any Java object which implements the ComponentLifeCycle interface and uses dependency injection to configure itself.
Adding an instance of ComponentLifeCycle to the SpringJBIContainer will automatically wrap the POJO in a JBI ComponentAdaptor so that it faithfully obeys the JBI Component contract.
This means you can write JBI POJOs to be deployed by Spring without deriving from some helper base class like ServiceMix's ComponentSupport so that your POJO has no dependency other than on the JBI APIs and then let ServiceMix take care of more of the plumbing for you.
Example POJO Components
First here's how we configure the two components in ServiceMix. Notice that ServiceMix is doing the routing here using destinationService.
<beans xmlns:sm="http://servicemix.apache.org/config/1.0"
xmlns:foo="http://servicemix.org/cheese/">
<sm:container id="jbi" embedded="true">
<sm:activationSpecs>
<sm:activationSpec componentName="sender" service="foo:sender" destinationService="foo:receiver">
<sm:component><bean class="org.apache.servicemix.components.pojo.MySender" /></sm:component>
</sm:activationSpec>
<sm:activationSpec id="receiver" service="foo:receiver">
<sm:component><bean class="org.apache.servicemix.components.pojo.MyReceiver"/></sm:component>
</sm:activationSpec>
</sm:activationSpecs>
</sm:container>
</beans>
Now lets look at the sender POJO. The sendMessages() method will send messages onto the JBI bus to the destination service specified in the above XML.
public class MySender implements ComponentLifeCycle {
private ComponentContext context;
private ObjectName extensionMBeanName;
/**
* Sends a number of messages
*/
public void sendMessages(int count) throws MessagingException {
DeliveryChannel deliveryChannel = context.getDeliveryChannel();
MessageExchangeFactory factory = deliveryChannel.createExchangeFactory();
for (int i = 0; i < count; i++) {
InOnly exchange = factory.createInOnlyExchange();
NormalizedMessage message = exchange.createMessage();
exchange.setInMessage(message);
message.setProperty("id", new Integer(i));
message.setContent(new StringSource("<example id='" + i + "'/>"));
deliveryChannel.send(exchange);
}
}
public ObjectName getExtensionMBeanName() {
return extensionMBeanName;
}
public void init(ComponentContext context) throws JBIException {
this.context = context;
}
public void shutDown() throws JBIException {
}
public void start() throws JBIException {
}
public void stop() throws JBIException {
}
public void setExtensionMBeanName(ObjectName extensionMBeanName) {
this.extensionMBeanName = extensionMBeanName;
}
}
Then the receiver processes inbound messages as follows.
public class MyReceiver implements ComponentLifeCycle, MessageExchangeListener {
private static final Log log = LogFactory.getLog(MyReceiver.class);
private ComponentContext context;
private ObjectName extensionMBeanName;
private MessageList messageList = new MessageList();
public ObjectName getExtensionMBeanName() {
return extensionMBeanName;
}
public void init(ComponentContext context) throws JBIException {
this.context = context;
context.activateEndpoint(new QName("http:, "receiver"), "receiver");
}
public void shutDown() throws JBIException {
}
public void start() throws JBIException {
}
public void stop() throws JBIException {
}
public void onMessageExchange(MessageExchange exchange) throws MessagingException {
log.info("Received message " + exchange);
NormalizedMessage message = exchange.getMessage("in");
getMessageList().addMessage(message);
exchange.setStatus(ExchangeStatus.DONE);
context.getDeliveryChannel().send(exchange);
}
public void setExtensionMBeanName(ObjectName extensionMBeanName) {
this.extensionMBeanName = extensionMBeanName;
}
public MessageList getMessageList() {
return messageList;
}
public void setMessageList(MessageList messageList) {
this.messageList = messageList;
}
}
Being even more POJO
The code above may seem a bit too verbose for you. Firstly you can reduce much code by reusing the Component helper classes.
Another option is to be even more POJO-like. If you just want to invoke operations on the JBI bus then there's no need for you to implement the JBI component or lifecycle contract - you can just reuse the Client API.
For example this POJO sends messages into the JBI bus.
public class PojoSender {
private ServiceMixClient client;
public void sendMessages(int count) throws MessagingException {
for (int i = 0; i < count; i++) {
InOnly exchange = client.createInOnlyExchange();
NormalizedMessage message = exchange.getInMessage();
message.setProperty("id", new Integer(i));
message.setContent(new StringSource("<example id='" + i + "'/>"));
client.send(exchange);
}
}
public ServiceMixClient getClient() {
return client;
}
public void setClient(ServiceMixClient client) {
this.client = client;
}
}
And this is a POJO receiver which just consumes the messages its given, without explicitly implementing the component or lifecycle interfaces
public class PojoReceiver implements MessageExchangeListener {
private MessageList messageList = new MessageList();
public void onMessageExchange(MessageExchange exchange) throws MessagingException {
NormalizedMessage message = exchange.getMessage("in");
getMessageList().addMessage(message);
}
public MessageList getMessageList() {
return messageList;
}
}