In the past tutorial, we had learned how to start a Spring JMS ActiveMQ application with auto-configured ConnectionFactory by SpringBoot.
But in the software development, there’re many cases that we need to override the ContainerFactory, so How to do it? JavaSampleApproach makes the tutorial to guide how to explicitly configure Spring ActiveMQ ConnectionFactory.
Related posts:
– How to use Spring JMS with ActiveMQ – JMS Consumer and JMS Producer | Spring Boot
– How to start Spring Kafka Application with Spring Boot
– Spring Jms ActiveMq – How to send Java object messages to ActiveMQ server (specially with Bi-Directional relationship Java objects)
– ActiveMq – How to work with Spring JMS ActiveMq Topic (Publisher-Subcribers pattern) using SpringBoot
Contents
I. Technologies
– Java 8
– Maven 3.6.1
– Spring Tool Suite: Version 3.8.4.RELEASE
– Spring Boot: 1.5.4.RELEASE
– Apache ActiveMQ 5.13.0
II. Spring ActiveMq connection-factory
For configuring ActiveMQ ContainerFactory, we need to setup a new bean ConnectionFactory
to override the auto-configured connection-factory bean of SpringBoot.
... @Bean public ConnectionFactory connectionFactory(){ ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(); ... return connectionFactory; } |
Then use the ConnectionFactory
bean to configure 2 beans {JmsListenerContainerFactory, JmsTemplate}:
/* * Used for Receiving Message */ @Bean public JmsListenerContainerFactory<?> jsaFactory(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); ... return factory; } /* * Used for Sending Messages. */ @Bean public JmsTemplate jmsTemplate(){ ... return template; } ... |
– JmsTemplate
bean is used to send Jms messages.
– JmsListenerContainerFactory
is used to listen Jms messages.
III. Practice
In the tutorial, We use SpringBoot to create a Spring JMS ActiveMQ application with explicitly ActiveMQ-ConnectionFactory configuration.
Step to do
– Create SpringBoot project
– Explicitly configure ActiveMq connection-factory
– Implement JmsProducer, JmsListener
– Create a simple RestApi
– Run and check resutls
1. Create SpringBoot project
Using Spring Tool Suite to create a Spring Starter Project, then add dependencies:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> |
2. Explicitly configure ActiveMq connection-factory
– Create a Java configuration file ActiveMqConnectionFactoryConfig for 3 beans {ConnectionFactory, JmsListenerContainerFactory, JmsTemplate}
package com.javasampleapproach.activemq.config; import javax.jms.ConnectionFactory; import org.apache.activemq.ActiveMQConnectionFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jms.config.DefaultJmsListenerContainerFactory; import org.springframework.jms.config.JmsListenerContainerFactory; import org.springframework.jms.core.JmsTemplate; @Configuration public class ActiveMqConnectionFactoryConfig { @Value("${jsa.activemq.broker.url}") String brokerUrl; @Value("${jsa.activemq.borker.username}") String userName; @Value("${jsa.activemq.borker.password}") String password; /* * Initial ConnectionFactory */ @Bean public ConnectionFactory connectionFactory(){ ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(); connectionFactory.setBrokerURL(brokerUrl); connectionFactory.setUserName(userName); connectionFactory.setPassword(password); return connectionFactory; } /* * Used for Receiving Message */ @Bean public JmsListenerContainerFactory<?> jsaFactory(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); configurer.configure(factory, connectionFactory); return factory; } /* * Used for Sending Messages. */ @Bean public JmsTemplate jmsTemplate(){ JmsTemplate template = new JmsTemplate(); template.setConnectionFactory(connectionFactory()); return template; } } |
Open application.properties file, makes configuration for {brokerUrl, userName, password, queue}:
jsa.activemq.broker.url=tcp://localhost:61616 jsa.activemq.borker.username=admin jsa.activemq.borker.password=admin jsa.activemq.queue=jsa-queue |
3. Implement JmsProducer, JmsListener
Use JmsTemplate which had been setup in ActiveMqConnectionFactoryConfig to create a JmsProducer component for sending Jms messages:
package com.javasampleapproach.activemq.jms.producer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.jms.core.JmsTemplate; import org.springframework.stereotype.Component; @Component public class JmsProducer { @Autowired JmsTemplate jmsTemplate; @Value("${jsa.activemq.queue}") String queue; public void send(String msg){ jmsTemplate.convertAndSend(queue, msg); } } |
Use annotation @JmsListener
and jsaFactory containerFactory (which had been setup in ActiveMqConnectionFactoryConfig) to create a JmsConsumer component for listenning Jms messages:
package com.javasampleapproach.activemq.jms.consumer; import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; @Component public class JmsConsumer { @JmsListener(destination = "${jsa.activemq.queue}", containerFactory="jsaFactory") public void receive(String msg){ System.out.println("Recieved Message: " + msg); } } |
4. Create a simple RestApi
Create a simple RestController with only one restApi: ‘/produce’ for sending message:
package com.javasampleapproach.activemq.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.javasampleapproach.activemq.jms.producer.JmsProducer; @RestController public class WebController { @Autowired JmsProducer jmsProducer; @RequestMapping(value="/produce") public String produce(@RequestParam("msg")String msg){ jmsProducer.send(msg); return "Done"; } } |
5. Run and check resutls
Start ActiveMQ server with commandline: C:\apache-activemq-5.13.0>.\bin\activemq start
.
Build and Run the SpringBoot project with commandlines: mvn clean install
and mvn spring-boot:run
Now sending messages with 2 requests:
http://localhost:8080/produce?msg=Hello World!
-> Server Log: “Recieved Message: Hello World!”
http://localhost:8080/produce?msg=This is a message from JavaSampleApproach!
-> Server Log: “Recieved Message: This is a message from JavaSampleApproach!”