21.2.3. Receiving messages using a message-driven bean
You can process messages with any EJB3 message-driven bean. Message-driven beans can sometimes be Seam components, in which case, you can inject other event- and application-scoped Seam components. The following is an example of the payment receiver, which delegates to the payment processor.
Note
You may need to set the
create
attribute on the @In
annotation to true
so that Seam can create an instance of the component to be injected. (This is necessary only if the component does not support auto-creation — that is, it is not annotated with @Autocreate
.)
First, create a message-driven bean to receive the message:
@MessageDriven(activationConfig = {@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/paymentQueue") }) @Name("paymentReceiver") public class PaymentReceiver implements MessageListener { @Logger private Log log; @In(create = true) private PaymentProcessor paymentProcessor; @Override public void onMessage(Message message) { try { paymentProcessor.processPayment((Payment) ((ObjectMessage) message).getObject()); } catch (JMSException ex) { log.error("Message payload did not contain a Payment object", ex); } } }
Next, implement the Seam component to which the receiver will delegate payment processing:
@Name("paymentProcessor") public class PaymentProcessor { @In private EntityManager entityManager; public void processPayment(Payment payment) { // perhaps do something more fancy entityManager.persist(payment); } }
If you want to perform transaction operations in your message-driven bean, ensure that you are working with an XA datasource, or you will not be able to roll back database changes in the event that a database transaction commits, but a subsequent message operation fails.