blob: d19ec02ecce47277e02bd18c3fc988b33840ca25 [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" class="external-link" href="http://codedependents.com/2009/10/16/efficient-lightweight-jms-with-spring-and-activemq/" rel="nofollow">article</a> on using Spring with ActiveMQ - I'd recommend reading it first.</p><h2 id="SpringSupport-ConfiguringtheJMSclient">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" class="external-link" 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" class="external-link" 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><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[&lt;bean id=&quot;jmsFactory&quot; class=&quot;org.apache.activemq.ActiveMQConnectionFactory&quot;&gt;
&lt;property name=&quot;brokerURL&quot;&gt;
&lt;value&gt;tcp://localhost:61616&lt;/value&gt;
&lt;/property&gt;
&lt;/bean&gt;
]]></script>
</div></div><p>The following shows how to use Zeroconf to discover the available brokers to connect to.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[&lt;bean id=&quot;jmsFactory&quot; class=&quot;org.apache.activemq.ActiveMQConnectionFactory&quot;&gt;
&lt;property name=&quot;brokerURL&quot;&gt;
&lt;value&gt;zeroconf://_activemq.broker.development.&lt;/value&gt;
&lt;/property&gt;
&lt;/bean&gt;
]]></script>
</div></div><p>From 1.1 of ActiveMQ onwards you can also use JNDI to configure ActiveMQ within Spring. <a shape="rect" class="external-link" 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 <a shape="rect" href="jndi-support.xml">JNDI Support</a>.</p><h3 id="SpringSupport-UsingSpring">Using Spring</h3><p>If you are using the new <a shape="rect" class="external-link" href="http://static.springframework.org/spring/docs/2.0.x/reference/xsd-config.html" rel="nofollow">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><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[&lt;beans
xmlns=&quot;http://www.springframework.org/schema/beans&quot;
xmlns:amq=&quot;http://activemq.apache.org/schema/core&quot;
xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
xsi:schemaLocation=&quot;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&quot;&gt;
&lt;amq:broker useJmx=&quot;false&quot; persistent=&quot;false&quot;&gt;
&lt;amq:transportConnectors&gt;
&lt;amq:transportConnector uri=&quot;tcp://localhost:0&quot; /&gt;
&lt;/amq:transportConnectors&gt;
&lt;/amq:broker&gt;
&lt;amq:connectionFactory id=&quot;jmsFactory&quot; brokerURL=&quot;vm://localhost&quot;/&gt;
&lt;/beans&gt;
]]></script>
</div></div><p>This allows you to configure JMS artifacts like destinations and connection factories together with the entire broker.</p><h2 id="SpringSupport-WorkingwithSpring'sJmsTemplate">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 <a shape="rect" href="jmstemplate-gotchas.xml">JmsTemplate Gotchas</a> 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><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[&lt;!-- a pooling based JMS provider --&gt;
&lt;bean id=&quot;jmsFactory&quot; class=&quot;org.apache.activemq.pool.PooledConnectionFactory&quot; destroy-method=&quot;stop&quot;&gt;
&lt;property name=&quot;connectionFactory&quot;&gt;
&lt;bean class=&quot;org.apache.activemq.ActiveMQConnectionFactory&quot;&gt;
&lt;property name=&quot;brokerURL&quot;&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=&quot;myJmsTemplate&quot; class=&quot;org.springframework.jms.core.JmsTemplate&quot;&gt;
&lt;property name=&quot;connectionFactory&quot;&gt;
&lt;ref local=&quot;jmsFactory&quot;/&gt;
&lt;/property&gt;
&lt;/bean&gt;
]]></script>
</div></div><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" class="external-link" href="http://camel.apache.org/activemq.html">Camel</a> and Spring's <a shape="rect" class="external-link" 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 id="SpringSupport-ConsumingJMSfrominsideSpring">Consuming JMS from inside Spring</h2><p>Spring's <a shape="rect" class="external-link" href="http://static.springsource.org/spring/docs/2.5.x/reference/jms.html#jms-mdp" rel="nofollow">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 id="SpringSupport-MoreInformation">More Information</h2><p>Also check out the following blogs for information about using Spring JMS with ActiveMQ:</p><ul><li><a shape="rect" class="external-link" href="http://codedependents.com/2010/03/04/synchronous-request-response-with-activemq-and-spring/" rel="nofollow">Synchronous Request Response with ActiveMQ and Spring</a></li><li><a shape="rect" class="external-link" href="http://bsnyderblog.blogspot.com/2010/02/using-spring-jmstemplate-to-send-jms.html" rel="nofollow">Using Spring to Send JMS Messages</a></li><li><a shape="rect" class="external-link" href="http://bsnyderblog.blogspot.com/2010/02/using-spring-to-receive-jms-messages.html" rel="nofollow">Using Spring to Receive JMS Messages</a></li><li><a shape="rect" class="external-link" href="http://bsnyderblog.blogspot.com/2010/05/tuning-jms-message-consumption-in.html" rel="nofollow">Tuning JMS Message Consumption In Spring</a></li></ul></div>