45
Enterprise Messaging With Spring JMS Bruce Snyder, Senior Software Engineer, SpringSource Friday, July 8, 2011

Enterprise Messaging With Spring JMS

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Enterprise Messaging With Spring JMS

Enterprise Messaging With Spring JMS

Bruce Snyder, Senior Software Engineer, SpringSource

Friday, July 8, 2011

Page 2: Enterprise Messaging With Spring JMS

Agenda

• Very brief introduction to JMS • Synchronous JMS With Spring • Asynchronous JMS With Spring

2

Friday, July 8, 2011

Page 3: Enterprise Messaging With Spring JMS

What is JMS?

• JMS is:– An API for client-side communications with a JMS provider – Included in Java EE

• Also stand alone

• JMS is not: – A spec for a message broker implementation

3

Friday, July 8, 2011

Page 4: Enterprise Messaging With Spring JMS

JMS is an Abstraction

4

Friday, July 8, 2011

Page 5: Enterprise Messaging With Spring JMS

JMS Message

5

Friday, July 8, 2011

Page 6: Enterprise Messaging With Spring JMS

Point-to-Point Messaging

6

Friday, July 8, 2011

Page 7: Enterprise Messaging With Spring JMS

Publish/Subscribe Messaging

7

Friday, July 8, 2011

Page 8: Enterprise Messaging With Spring JMS

Typical JMS Use

8

Friday, July 8, 2011

Page 9: Enterprise Messaging With Spring JMS

Raw JMS

9

Friday, July 8, 2011

Page 10: Enterprise Messaging With Spring JMS

JMS With Spring

10

Friday, July 8, 2011

Page 11: Enterprise Messaging With Spring JMS

Managed vs. Non-Managed JMS

• Managed– JMS provider in a Java EE container – JMS resource pooling – Transaction support – Support for EJBs

• Non-Managed– Stand alone JMS provider – Manual setup of JMS resources – No guarantee of transactions

• Spring supports both environments

11

Friday, July 8, 2011

Page 12: Enterprise Messaging With Spring JMS

JMS With Spring

12

Friday, July 8, 2011

Page 13: Enterprise Messaging With Spring JMS

Spring JMS

• JMS Template– Send and receive messages

synchronously

• Message Listener Container – Receive messages asynchronously – Message-Driven POJOs (MDPs)

13

Friday, July 8, 2011

Page 14: Enterprise Messaging With Spring JMS

JmsTemplate

• browse() – Browse messages in a queue

• convertAndSend() – Send messages synchronously– Convert a Java object to a JMS message

• send() – Send a message synchronously using a MessageCreator

• receive() and receiveAndConvert() – Receive messages synchronously

• execute() – Provides access to callbacks for more complex scenarios

• receiveSelected() and receiveSelectedAndConvert()– Receive filtered messages synchronously

14

Synchronous

Friday, July 8, 2011

Page 15: Enterprise Messaging With Spring JMS

The Spring JmsTemplate

15

<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory" p:brokerURL="tcp://localhost:61616" /> <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg value="FOO.TEST" /> </bean> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate" p:connectionFactory-ref="connectionFactory" p:defaultDestination-ref="destination" />

<bean id="messageProducer" class="org.bsnyder.spring.jms.producer.SimpleMessageProducer" p:jmsTemplate-ref="jmsTemplate" />

Synchronous

Friday, July 8, 2011

Page 16: Enterprise Messaging With Spring JMS

The Spring JmsTemplate

16

// Use the default destination jmsTemplate.convertAndSend("Hello World!");

// Use a different destinationjmsTemplate.convertAndSend(“TEST.BAR”, “Hello World!”);

// Use a different destinationString textMessage1 = (String) jmsTemplate.receiveAndConvert();

// Use a different destinationString textMessage2 = (String) jmsTemplate.receiveAndConvert(“TEST.BAR”);

Synchronous

Friday, July 8, 2011

Page 17: Enterprise Messaging With Spring JMS

The Spring JmsTemplate

• Using send() with a MessageCreator

17

// Use a MessageCreator callback jmsTemplate.send(destination, new MessageCreator() { public Message createMessage(Session session) throws JMSException { TextMessage message = session.createTextMessage("Hello World!"); message.setIntProperty("someBusinessId", 22); return message; } });

// Receive raw JMS message TextMessage message = jmsTemplate.receive();

Synchronous

Friday, July 8, 2011

Page 18: Enterprise Messaging With Spring JMS

The Spring JmsTemplate

• Using execute() and the SessionCallback

18

// Use a SessionCallbackjmsTemplate.execute(new SessionCallback() { public Object doInJms(Session session) throws JMSException { Queue queue = session.createQueue("MY.TEST.QUEUE"); MessageProducer producer = session.createProducer(queue); TextMessage message = session.createTextMessage("Hello World!"); producer.send(message); }});

Synchronous

Friday, July 8, 2011

Page 19: Enterprise Messaging With Spring JMS

The Spring JmsTemplate

• Using execute() with the ProducerCallback

19

// Use a ProducerCallbackjmsTemplate.execute(new ProducerCallback() { public Object doInJms(Session session, MessageProducer producer) throws JMSException { TextMessage message = session.createTextMessage("Hello World!"); producer.send(destination, message); } return null; }});

Synchronous

Friday, July 8, 2011

Page 20: Enterprise Messaging With Spring JMS

The Spring JmsTemplate

• Using JMS selector expression

20

// Using a selector expression String selectorExpression = “Timestamp BETWEEN 1218048453251 AND 1218048484330”;

jmsTemplate.receiveSelected(destination, selectorExpression);

Synchronous

Friday, July 8, 2011

Page 21: Enterprise Messaging With Spring JMS

The Spring JmsTemplate

• Resolving JMS destinations – DynamicDestinationResolver (default)

• Look up destinations via a simple text name • Just calls session.createQueue() and session.createTopic()

– JndiDestinationResolver• Option to fall back to DynamicDestinationResolver

– BeanFactoryDestinationResolver• Look up beans that are javax.jms.Destination objects

21

Synchronous

Friday, July 8, 2011

Page 22: Enterprise Messaging With Spring JMS

The Spring JmsTemplate

• MessageConverter – SimpleMessageConverter

• String <-> javax.jms.TextMessage• Map <-> javax.jms.MapMessage• Serializable object <-> javax.jms.ObjectMessage• byte[] <-> javax.jms.BytesMessage

22

Synchronous

Friday, July 8, 2011

Page 23: Enterprise Messaging With Spring JMS

The Spring JmsTemplate

• JmsException hierarchy – Spring-specific unchecked exceptions – Corresponds to JMSException

• Advantage – Automatic clean up of JMS resources

23

Synchronous

Friday, July 8, 2011

Page 24: Enterprise Messaging With Spring JMS

The Spring JmsTemplate

• Automatically participates in transactions • Provides support for:

– Java EE transactions – Spring local transactions (Spring JmsTransactionManager)– Spring global transactions (Spring JtaTransactionManager)

• XA requires an XA capable ConnectionFactory • XA resource enlistment is provider specific

24

Synchronous

Friday, July 8, 2011

Page 25: Enterprise Messaging With Spring JMS

The Spring JmsTemplate

• JmsTemplate does not provide resource pooling – Utilizes fresh connection/session for every invocation

• JMS resource pooling is responsibility of JMS provider

• Spring provides support – SingleConnectionFactory

• Returns same connection for all calls to createConnection()• Ignores all calls to close()

– CachingConnectionFactory• Extends SingleConnectionFactory to add Session caching and

automatic Connection recovery

25

Synchronous

Friday, July 8, 2011

Page 26: Enterprise Messaging With Spring JMS

Spring JMS

• JMS Template– Send and receive messages

synchronously

• Message Listener Container – Receive messages asynchronously – Message-Driven POJOs (MDPs)

26

Friday, July 8, 2011

Page 27: Enterprise Messaging With Spring JMS

Managed vs. Non-Managed JMS

• Non-Managed – JMS MessageConsumer registers a MessageListener – Manual lifecycle management

• Managed – EJB Message-Driven Beans

27

Asynchronous

Friday, July 8, 2011

Page 28: Enterprise Messaging With Spring JMS

JMS Transaction Support

• Non-Managed XA Transactions – A JMS MessageConsumer can use various acknowledge

modes • AUTO_ACKNOWLEDGE• CLIENT_ACKNOWLEDGE• DUPS_OK_ACKNOWLEDGE• local JMS transaction

– Standard JMS does not support asynchronous message consumption as part of a XA transaction

• Managed XA Transactions – Officially supported only by EJBs

28

Asynchronous

Friday, July 8, 2011

Page 29: Enterprise Messaging With Spring JMS

Spring Message-Driven POJOs

• DefaultMessageListenerContainer– Most commonly used container – Allows for dynamic scaling of queue consumers– Participates in external transactions

• SimpleMessageListenerContainer– Very basic – Static configuration– No external transaction support

29

Asynchronous

Friday, July 8, 2011

Page 30: Enterprise Messaging With Spring JMS

DefaultMessageListenerContainer

• Highly configurable – Dynamic scale up/down of consumers

• Threads managed by the container – Customizable via the Spring TaskExecutor

• Resource caching– Connection, Session, MessageConsumer – Default is to cache nothing so as work in Java EE

environments– See the setCacheLevel() method for more info

• Works in managed and non-managed environments• Supports XA message consumption

30

Asynchronous

Friday, July 8, 2011

Page 31: Enterprise Messaging With Spring JMS

SimpleMessageListenerContainer

• No dynamic scaling of consumers • No support for XA transactions

31

Asynchronous

Friday, July 8, 2011

Page 32: Enterprise Messaging With Spring JMS

Supported Types of Message Listeners

• javax.jms.MessageListener interface – Standard Java EE interface – Threading is up to you

• SessionAwareMessageListener interface– Spring-specific interface – Provides access to the Session object

• Very useful for request-response messaging• MessageListenerAdapter interface

– Spring-specific interface – Allows for type-specific message handling – No JMS dependencies whatsoever

32

Asynchronous

Friday, July 8, 2011

Page 33: Enterprise Messaging With Spring JMS

MessageListener

• Standard JMS MessageListener • Uses an onMessage() method

33

public class MyMessageListener implements MessageListener { private static Logger LOG = Logger.getLogger(MyMessageListener.class); public void onMessage(Message message) throws JMSException { try { LOG.info("Consumed message: “ + message); // Do some processing here } catch (JMSException e) { LOG.error(e.getMessage(), e); } }

Asynchronous

Friday, July 8, 2011

Page 34: Enterprise Messaging With Spring JMS

DefaultMessageListenerContainer

• XML configuration

34

<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory" p:brokerURL="tcp://localhost:61616" />

<bean id="messageListener" class="org.bsnyder.spring.jms.listener.SimpleMessageListener" />

<jms:listener-container concurrency="5-10"> <jms:listener destination="FOO.TEST" ref="messageListener"/> </jms:listener-container>

Asynchronous

Friday, July 8, 2011

Page 35: Enterprise Messaging With Spring JMS

DefaultMessageListenerContainer

• Use more than one listener

35

<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory" p:brokerURL="tcp://localhost:61616" />

<bean id="widgetListener" class="org.bsnyder.spring.jms.listener.WidgetMessageListener" />

<bean id="gadgetListener" class="org.bsnyder.spring.jms.listener.GadgetMessageListener" />

<jms:listener-container concurrency="5-10"> <jms:listener destination="PRODUCTS.WIDGETS" ref="widgetListener"/> <jms:listener destination="PRODUCTS.GADGETS" ref="gadgetListener"/> </jms:listener-container>

Asynchronous

Friday, July 8, 2011

Page 36: Enterprise Messaging With Spring JMS

SessionAwareMessageListener

• Provides access to the session• Uses an onMessage() method

36

public class MySessionAwareMessageListener implements SessionAwareMessageListener { private static Logger LOG = Logger.getLogger(MySessionAwareMessageListener.class); public void onMessage(Message message, Session session) throws JMSException { try { LOG.info("Consumed message: “ + ((TextMessage)message).getText()); // Send a reply message TextMessage newMessage = session.createTextMessage(“This is a test”); MessageProducer producer = session.createProducer(message.getJMSReplyTo()); LOG.info("Sending reply message "); producer.send(newMessage); } catch (JMSException e) { LOG.error(e.getMessage(), e); } }}

Asynchronous

Friday, July 8, 2011

Page 37: Enterprise Messaging With Spring JMS

DefaultMessageListenerContainer

• XML configuration

37

<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory" p:brokerURL="tcp://localhost:61616" />

<bean id="messageListener" class="org.bsnyder.spring.jms.listener.MySessionAwareMessageListener" />

<jms:listener-container concurrency="5-10"> <jms:listener destination="FOO.TEST" ref="messageListener"/> </jms:listener-container>

Asynchronous

Friday, July 8, 2011

Page 38: Enterprise Messaging With Spring JMS

MessageListenerAdapter

• Handles all message content types• No reply message is sent (void return)

38

public interface MessageDelegate { void processMessage(String text); void processMessage(Map map); void processMessage(byte[] bytes); void processMessage(Serializable obj); }

Asynchronous

Friday, July 8, 2011

Page 39: Enterprise Messaging With Spring JMS

MessageListenerAdapter

39

<bean id="messageDelegate" class="org.springframework.jms.listener.adapter.MessageListenerAdapter" p:defaultListenerMethod="processMessage"> <constructor-arg> <bean class="org.bsnyder.spring.jms.adapter.MessageDelegateImpl" /> </constructor-arg> <property name="messageConverter"> <null/> </property> </bean>

<jms:listener-container concurrency="5-10"> <jms:listener destination="FOO.TEST" ref="messageDelegate" /> </jms:listener-container>

Asynchronous

Friday, July 8, 2011

Page 40: Enterprise Messaging With Spring JMS

MessageListenerAdapter

• Handles all raw JMS message types• No reply message is sent (void return)

40

public interface MessageDelegate { void processMessage(TextMessage message); void processMessage(MapMessage message); void processMessage(BytesMessage message); void processMessage(ObjectMessage message); }

Asynchronous

Friday, July 8, 2011

Page 41: Enterprise Messaging With Spring JMS

MessageListenerAdapter

41

<bean id="messageDelegate2" class="org.springframework.jms.listener.adapter.MessageListenerAdapter" p:defaultListenerMethod="processMessage"> <constructor-arg> <bean class="org.bsnyder.spring.jms.adapter.MessageDelegate2Impl" /> </constructor-arg> <property name="messageConverter"> <null/> </property> </bean>

<jms:listener-container concurrency="5-10"> <jms:listener destination="FOO.TEST2" ref="messageDelegate2" /> </jms:listener-container>

Asynchronous

Friday, July 8, 2011

Page 42: Enterprise Messaging With Spring JMS

Local Transactions

42

Asynchronous

<bean id="messageDelegate" class="org.springframework.jms.listener.adapter.MessageListenerAdapter" p:defaultListenerMethod="processMessage"> <constructor-arg> <bean class="org.bsnyder.spring.jms.adapter.MessageDelegateImpl" /> </constructor-arg> <property name="messageConverter"> <null/> </property> </bean>

<jms:listener-container concurrency="5-10" acknowledge=”transacted”> <jms:listener destination="FOO.TEST" ref="messageDelegate" /> </jms:listener-container>

Friday, July 8, 2011

Page 43: Enterprise Messaging With Spring JMS

Global Transactions

43

Asynchronous

<bean id="activemqXaConnectionFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory" p:brokerURL="tcp://localhost:61616" />

<bean id="atomikosConnectionFactory" class="com.atomikos.jms.AtomikosConnectionFactoryBean" init-method="init" destroy-method="close"> <property name="uniqueResourceName" value="simpleTransaction"/> <property name="xaConnectionFactory" ref="activemqXaConnectionFactory"/> </bean>

<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.J2eeTransactionManager" /> <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.J2eeUserTransaction" /> <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" p:transactionManager-ref="atomikosTransactionManager" p:userTransaction-ref="atomikosUserTransaction"> </bean>...

Friday, July 8, 2011

Page 44: Enterprise Messaging With Spring JMS

Global Transactions

44

Asynchronous

...

<bean id="messageDelegate" class="org.springframework.jms.listener.adapter.MessageListenerAdapter" p:defaultListenerMethod="processMessage"> <constructor-arg> <bean class="org.bsnyder.spring.jms.adapter.MessageDelegateImpl" /> </constructor-arg> <property name="messageConverter"> <null/> </property> </bean>

<jms:listener-container concurrency="5-10" connection-factory="atomikosConnectionFactory" transaction-manager="transactionManager" acknowledge="transacted"> <jms:listener destination="FOO.TEST" ref="messageDelegate" /> </jms:listener-container>

Friday, July 8, 2011

Page 45: Enterprise Messaging With Spring JMS

Q&A

Thank You!

Friday, July 8, 2011