blob: 20acbcc16c9f5cd972f2df47a821a74c717c7ef5 [file] [log] [blame]
<div class="wiki-content maincontent"><p>We fully support Spring for configuration of the JMS client side as well as for configuring the JMS Message Broker.<br clear="none"> There is a great <a shape="rect" href="http://codedependents.com/2009/10/16/efficient-lightweight-jms-with-spring-and-activemq/">article</a> on using Spring with ActiveMQ - I'd recommend reading it first.</p><h2>Configuring the JMS client</h2><p>To configure an ActiveMQ JMS client in Spring it is just a simple matter of configuring an instance of ActiveMQConnectionFactory within a standard Spring XML configuration file like any other bean. There are <a shape="rect" href="https://svn.apache.org/repos/asf/activemq/trunk/activemq-unit-tests/src/test/java/org/apache/activemq/spring/">several examples and test cases</a> available and <a shape="rect" href="https://svn.apache.org/repos/asf/activemq/trunk/activemq-unit-tests/src/test/resources/org/apache/activemq/xbean/spring.xml">this one</a> shows how to construct an ActiveMQConnectionFactory in Spring which is then passed into a Spring JmsTemplate for use by some POJOs.</p><p>e.g. the following fragment of XML shows us creating a JMS connection factory for ActiveMQ connecting to a remote broker on a specific host name and port.</p><structured-macro ac:macro-id="6b350c16-e02b-4b9c-ae89-0c6d63a34f67" ac:name="code" ac:schema-version="1"><parameter ac:name="">xml</parameter><plain-text-body>&lt;bean id="jmsFactory" class="org.apache.activemq.ActiveMQConnectionFactory"&gt;
&lt;property name="brokerURL"&gt;
&lt;value&gt;tcp://localhost:61616&lt;/value&gt;
&lt;/property&gt;
&lt;/bean&gt;
</plain-text-body></structured-macro><p>The following shows how to use Zeroconf to discover the available brokers to connect to.</p><structured-macro ac:macro-id="1bb25c22-6ae3-4534-b2d5-aa173d68a571" ac:name="code" ac:schema-version="1"><parameter ac:name="">xml</parameter><plain-text-body>&lt;bean id="jmsFactory" class="org.apache.activemq.ActiveMQConnectionFactory"&gt;
&lt;property name="brokerURL"&gt;
&lt;value&gt;zeroconf://_activemq.broker.development.&lt;/value&gt;
&lt;/property&gt;
&lt;/bean&gt;
</plain-text-body></structured-macro><p>From 1.1 of ActiveMQ onwards you can also use JNDI to configure ActiveMQ within Spring. <a shape="rect" href="http://svn.apache.org/repos/asf/activemq/trunk/activemq-unit-tests/src/test/resources/spring-jndi.xml">This example</a> shows how to configure Spring using ActiveMQ's <link><page ri:content-title="JNDI Support"></page></link>.</p><h3>Using Spring</h3><p>If you are using the new <a shape="rect" href="http://static.springframework.org/spring/docs/2.0.x/reference/xsd-config.html">XML Schema-based configuration</a> of Spring 2.0 you can embed the ActiveMQ broker XML inside any regular Spring.xml file without requiring the above factory bean. e.g. here is an example of a regular Spring XML file in Spring 2.0 which also configures a broker.</p><structured-macro ac:macro-id="274a6400-3e58-4239-9a63-9514b52498ff" ac:name="code" ac:schema-version="1"><parameter ac:name="">xml</parameter><plain-text-body>&lt;beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"&gt;
&lt;amq:broker useJmx="false" persistent="false"&gt;
&lt;amq:transportConnectors&gt;
&lt;amq:transportConnector uri="tcp://localhost:0" /&gt;
&lt;/amq:transportConnectors&gt;
&lt;/amq:broker&gt;
&lt;amq:connectionFactory id="jmsFactory" brokerURL="vm://localhost"/&gt;
&lt;/beans&gt;
</plain-text-body></structured-macro><p>This allows you to configure JMS artifacts like destinations and connection factories together with the entire broker.</p><h2>Working with Spring's JmsTemplate</h2><p>Spring supports a handy abstraction, JmsTemplate, which allows you to hide some of the lower level JMS details when sending messages etc.</p><p>Please be aware that there are a number of <link><page ri:content-title="JmsTemplate Gotchas"></page></link> to be careful of.</p><p>One thing to bear in mind with JmsTemplate is that by default it will create a new connection, session, producer for each message sent - then close them all down again. This is very inefficient! It is done like this to work in EJB containers which tend to use a special ConnectionFactory which does pooling.</p><p>If you are not using a JCA container to manage your JMS connections, we recommend you use our pooling JMS connection provider, (org.apache.activemq.pool.PooledConnectionFactory) from the <code>activemq-pool</code> library, which will pool the JMS resources to work efficiently with Spring's JmsTemplate or with EJBs.</p><p>e.g.</p><structured-macro ac:macro-id="aa39875d-0c29-419b-8302-b1e5feea7803" ac:name="code" ac:schema-version="1"><parameter ac:name="">xml</parameter><plain-text-body>&lt;!-- a pooling based JMS provider --&gt;
&lt;bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop"&gt;
&lt;property name="connectionFactory"&gt;
&lt;bean class="org.apache.activemq.ActiveMQConnectionFactory"&gt;
&lt;property name="brokerURL"&gt;
&lt;value&gt;tcp://localhost:61616&lt;/value&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;!-- Spring JMS Template --&gt;
&lt;bean id="myJmsTemplate" class="org.springframework.jms.core.JmsTemplate"&gt;
&lt;property name="connectionFactory"&gt;
&lt;ref local="jmsFactory"/&gt;
&lt;/property&gt;
&lt;/bean&gt;
</plain-text-body></structured-macro><p>The <code>PooledConnectionFactory</code> supports the pooling of Connection, Session and MessageProducer instances so it can be used with tools like <a shape="rect" href="http://camel.apache.org/activemq.html">Camel</a> and Spring's <a shape="rect" href="http://activemq.apache.org/spring-support.html">JmsTemplate and MessagListenerContainer </a>. Connections, sessions and producers are returned to a pool after use so that they can be reused later without having to undergo the cost of creating them again.</p><p>Note: while the <code>PooledConnectionFactory</code> does allow the creation of a collection of active consumers, it does not 'pool' consumers. Pooling makes sense for connections, sessions and producers, which can be seldom-used resources, are expensive to create and can remain idle a minimal cost. Consumers, on the other hand, are usually just created at startup and left going, handling incoming messages as they come. When a consumer is complete, it's preferred to shut down it down rather than leave it idle and return it to a pool for later reuse: this is because, even if the consumer is idle, ActiveMQ will keep delivering messages to the consumer's prefetch buffer, where they'll get held up until the consumer is active again.</p><p>If you are creating a collection of consumers (for example, for multi-threaded message consumption), you should consider keeping a low prefetch value (e.g. 10 or 20), to ensure that all messages don't end up going to just one of the consumers.</p><p>We do also have a pooling JMS ConnectionFactory for use inside a JCA / MDB container (org.apache.activemq.ra.InboundConnectionProxyFactory), when using our JCA Resource Adapter which will reuse the same JMS connection/session which is being used for inbound messages.</p><h2>Consuming JMS from inside Spring</h2><p>Spring's <a shape="rect" href="http://static.springsource.org/spring/docs/2.5.x/reference/jms.html#jms-mdp">MessagListenerContainer</a> should be used for message consumption. This provides all the power of MDBs - efficient JMS consumption and pooling of the message listeners - but without requiring a full EJB container.</p><p>You can use the <code>activemq-pool</code> <code>org.apache.activemq.pool.PooledConnectionFactory</code> for efficient pooling of the connections and sessions for your collection of consumers, or you can use the Spring JMS <code>org.springframework.jms.connection.CachingConnectionFactory</code> to achieve the same effect.</p><h2>More Information</h2><p>Also check out the following blogs for information about using Spring JMS with ActiveMQ:</p><ul><li><a shape="rect" href="http://codedependents.com/2010/03/04/synchronous-request-response-with-activemq-and-spring/">Synchronous Request Response with ActiveMQ and Spring</a></li><li><a shape="rect" href="http://bsnyderblog.blogspot.com/2010/02/using-spring-jmstemplate-to-send-jms.html">Using Spring to Send JMS Messages</a></li><li><a shape="rect" href="http://bsnyderblog.blogspot.com/2010/02/using-spring-to-receive-jms-messages.html">Using Spring to Receive JMS Messages</a></li><li><a shape="rect" href="http://bsnyderblog.blogspot.com/2010/05/tuning-jms-message-consumption-in.html">Tuning JMS Message Consumption In Spring</a></li></ul></div>