ActiveMq – Explicitly configure Spring ActiveMq ConnectionFactory with SpringBoot

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

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.

spring activemq connectionfactory - architecture ws

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!”

spring activemq connectionfactory - activemq console

IV. Sourcecode

SpringActiveMq-ConnectionFactory



By grokonez | June 30, 2017.

Last updated on April 29, 2021.



Related Posts


Got Something To Say:

Your email address will not be published. Required fields are marked *

*