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

Enterprise Messaging With Spring JMS

Nov 29, 2014

Download

Technology

Bruce Snyder

 
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
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