Статьи

Spring Boot Пример Spring Integration и ActiveMQ

В этой статье я расскажу вам, как использовать Spring Boot для настройки примера Hello World с использованием Spring Integration и ActiveMQ . Мы настроим Spring Integration для прослушивания очереди ActiveMQ. Для забавы я буду использовать Spock, чтобы поместить сообщение в очередь, и мы можем наблюдать, как Spring Integration получает сообщение JMS и распечатывает сообщение на консоли.

Настройка проекта Spring Boot

Весенний инициализр

Используя IntelliJ для создания нового проекта, я выберу опцию использования Spring Initializr для создания моего нового проекта Spring Boot. Диалог IntellIj позволяет легко создать проект Spring Boot.

В этом случае я выбираю последнюю версию Spring Boot (1.3.0.M3) на момент написания и опцию Spring Integration.

IntelliJ и Spring Initializr

После выполнения шагов в IntelliJ у меня будет свежий проект Maven для работы с этим примером.

Spring Integration и ActiveMQ Dependencies

Spring Boot неплохо справляется с поиском основных зависимостей. Используя поддержку Maven в IntelliJ, мы можем посмотреть на зависимости Maven для нашего проекта. Вы можете видеть, что с помощью артефактов Spring Boot мы вводим основные зависимости для Spring Integration.

Spring Boot and Spring Integration maven dependencies in IntelliJ

 

At the time of writing, the Spring Initializr does not support ActiveMQ directly. I didn’t look to see if the Spring Boot team defined a Maven artifact for this or not. But, it’s simple enough to add the dependencies we will need for Spring Integration and ActiveMQ.

Notice how I have not added version information to the dependencies? That gets inherited from the parent Spring Boot Maven POM.

        <!--JMS support-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-jms</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-broker</artifactId>
        </dependency>

ActiveMQ Spring Boot Configuration

Like many other things, Spring Boot makes our task of configuring ActiveMQ easier. For the purposes of our example, we want to use an embedded ActiveMQ broker. This is common to use when developing Spring projects which use ActiveMQ. Often when developing enterprise applications using Spring, you will use a ActiveMQ embedded broker for development and then have a configuration to use IBM’s MQSeries in production.

ActiveMQ Broker

By just having ActiveMQ on our build path, Spring Boot will automatically set up a ActiveMQ broker. We need to set a couple properties to make it an in memory broker, without connection pooling. We can do this by setting two properties for Spring Boot.

application.properties

spring.activemq.in-memory=true
spring.activemq.pooled=false

ActiveMQ Queue Configuration

We also need to setup a queue for our example. We can do this in a Spring Java Configuration class as follows.

ActiveMQConfig.java

package guru.springframework.configuration;

import org.apache.activemq.command.ActiveMQQueue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.jms.Queue;

@Configuration
public class ActiveMQConfig {

    public static final String HELLO_QUEUE = "hello.queue";

    @Bean
    public Queue helloJMSQueue() {
        return new ActiveMQQueue(HELLO_QUEUE);
    }
}

This is all we need to do to configure ActiveMQ for our example. Spring Boot will take care of the rest.

Spring Integration Configuration

Spring Integration JMS Channel Adapter

Spring Integration comes with a number of different channel adapters. In this case, we need to configure a JMS channel adapter. This will serve as a transparent bridge between Spring Integration Messaging and JMS Messaging.

In the Spring Integration XML configuration below, I’ve defined a Spring Integration JMS channel adapter. The destination property is set to the name of the ActiveMQ queue bean we defined above. (When using Spring Java configuration, the bean reference becomes is inherited from the method name in the configuration class.) I’ve also added a Spring Integration channel to the configuration.

This acts as a bridge, messages coming from the JMS queue will get sent the the Spring Integration channel, and messages sent to the Spring Integration channel will get passed along to the JMS queue.

si-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jms="http://www.springframework.org/schema/integration/jms"
       xmlns:integration="http://www.springframework.org/schema/integration"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd">

    <jms:message-driven-channel-adapter id="helloJMSAdapater" destination="helloJMSQueue"
        channel="helloChannel"/>

    <integration:channel id="helloChannel"/>

</beans>

Say Hello Service

We’ll use a simple service for our example today. Its a Spring Service component, which simply takes a string in and prints it out to the console.

SayHelloService.java

package guru.springframework.services;


import org.springframework.stereotype.Service;

@Service
public class SayHelloService {
    public void sayHello(String name){
        System.out.println("################################");
        System.out.println("################################");
        System.out.println("################################");
        System.out.println("##  Hello " + name + "!!!" );
        System.out.println("################################");
        System.out.println("################################");
        System.out.println("################################");
    }
}

Spring Integration Service Activator Configuration

Next we need to add a Spring Integration Service Activator. This is what Spring Integration will use to process the message. We just need to add the following to our Spring Integration XML file.

/resources/spring/si-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jms="http://www.springframework.org/schema/integration/jms"
       xmlns:integration="http://www.springframework.org/schema/integration"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd">

    <jms:message-driven-channel-adapter id="helloJMSAdapater" destination="helloJMSQueue"
        channel="helloChannel"/>

    <integration:channel id="helloChannel"/>

    <integration:service-activator id="sayHelloServiceActivator" input-channel="helloChannel"
                                   ref="sayHelloService" method="sayHello"/>
</beans>

Spring Boot Configuration

We need to tell Spring Boot about the Spring Integration XML configuration file. We can to this by adding an ImportResource  annotation to the Spring Boot application class file as follows.

HelloWorldSiActivemqApplication.class

package guru.springframework;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;

@SpringBootApplication
@ImportResource("classpath*:/spring/si-config.xml")
public class HelloWorldSiActivemqApplication {

    public static void main(String[] args) {
        SpringApplication.run(HelloWorldSiActivemqApplication.class, args);
    }
}

Spock Configuration

Maven Dependencies

To enable Spock support add the following dependencies to your Maven pom file.

        <!--needed to support Spock-->
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.4.3</version>
        </dependency>
        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-core</artifactId>
            <version>1.0-groovy-2.4</version>
        </dependency>
        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-spring</artifactId>
            <version>1.0-groovy-2.4</version>
        </dependency>

Maven Compiler Plugin

Spock test classes are written in Groovy. You will need to add a Groovy compiler to your Maven build. I like to use the Groovy Eclipse Compiler. Add the following plugin to your build plugins.

            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <!-- 2.8.0-01 and later require maven-compiler-plugin 3.1 or higher -->
                <version>3.1</version>
                <configuration>
                    <compilerId>groovy-eclipse-compiler</compilerId>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.codehaus.groovy</groupId>
                        <artifactId>groovy-eclipse-compiler</artifactId>
                        <version>2.9.2-01</version>
                    </dependency>
                    <!-- for 2.8.0-01 and later you must have an explicit dependency on groovy-eclipse-batch -->
                    <dependency>
                        <groupId>org.codehaus.groovy</groupId>
                        <artifactId>groovy-eclipse-batch</artifactId>
                        <version>2.4.3-01</version>
                    </dependency>
                </dependencies>
            </plugin>

Sending a JMS Message Using Spock

There’s a lot of different ways to send a JMS message. I chose to use Spock for this example mostly for fun. I enjoy using Spock. In this example, I’ve setup Spock to use the same Spring context used by the Spring Boot Application. The Spring Boot Application class is actually a Spring Configuration class you can source into your Spring Integration tests.

Spock Spring Integration Test

In this Spock Integration test, using the Spring Boot configuration, I autowire in an instance of the JMS connection factory and setup a JMS producer to send a text message. This will drop a text message on the the same ActiveMQ JMS queue we configured Spring Integration to listen on.

SayHellowServiceJMSIT.groovy

package guru.springframework.services

import guru.springframework.HelloWorldSiActivemqApplication
import guru.springframework.configuration.ActiveMQConfig
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.boot.test.SpringApplicationContextLoader
import org.springframework.test.context.ContextConfiguration
import spock.lang.Specification

import javax.jms.Connection
import javax.jms.ConnectionFactory
import javax.jms.DeliveryMode
import javax.jms.Destination
import javax.jms.MessageProducer
import javax.jms.Session
import javax.jms.TextMessage

/**
 * Created by jt on 8/18/15.
 */
@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = [HelloWorldSiActivemqApplication])
class SayHelloServiceJmsIT extends Specification{

    @Autowired
    @Qualifier("jmsConnectionFactory")
    ConnectionFactory jmsConnectionFactory

    String queueName = ActiveMQConfig.HELLO_QUEUE
    Session session
    Destination destination
    MessageProducer producer

    def setup(){
        Connection conn = jmsConnectionFactory.createConnection()
        conn.start()
        session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE)
        destination = session.createQueue(queueName)
        this.producer = session.createProducer(destination)
        this.producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT)
    }

    def "Test Send and Receive of Message"() {
        given:
        TextMessage txtMessage = session.createTextMessage()
        txtMessage.setText("Larry the Cable Guy")

        when:
        producer.send(destination, txtMessage)

        sleep(3000) // wait 3 seconds
        then:
        true

    }
}

Running the Spock Integration Test

Using IntelliJ, running the Spock integration test can simply be done by right clicking on the test method, and then clicking on ‘run’.

running a spock test in Intellij

 

Test Output

Failed to load ApplicationContext

at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:228)
at org.spockframework.spring.SpringTestContextManager.prepareTestInstance(SpringTestContextManager.java:49)
at org.spockframework.spring.SpringInterceptor.interceptSetupMethod(SpringInterceptor.java:42)
at org.spockframework.runtime.extension.AbstractMethodInterceptor.intercept(AbstractMethodInterceptor.java:28)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:116)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloJMSAdapater.container': Cannot resolve reference to bean 'connectionFactory' while setting bean property 'connectionFactory'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'connectionFactory' is defined
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1481)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1226)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:305)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:834)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:667)
at org.springframework.boot.SpringApplication.doRun(SpringApplication.java:342)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:273)
at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:102)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
... 13 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'connectionFactory' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:698)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1174)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:283)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
... 31 more

Spring Integration JMS Configuration for Spring Boot

Intentionally left an error in the Spring Integration configuration to demonstrate this error. The Spring Integration configuration be default is looking for a Spring Bean called ‘connectionFactory’. Spring Boot by default, creates the JMS connection factory using the name ‘jmsConnectionFactory’.

The solution is easy enough to implement. We just need to update the Spring Integration channel adapter to use the Spring Bean ‘jmsConnectionFactory’ instead of it’s default value of ‘connectionFactory.

si-config.xml

 <jms:message-driven-channel-adapter id="helloJMSAdapater" destination="helloJMSQueue"
       connection-factory="jmsConnectionFactory"  channel="helloChannel"/>

Running the Updated Configuration

When we run the Spock Integration Test again, we can see our expected hello world message in the console output.

Test Output

 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::             (v1.3.0.M3)

2015-08-18 06:37:48.619  INFO 34248 --- [           main] g.s.services.SayHelloServiceJmsIT        : Starting SayHelloServiceJmsIT on Johns-MacBook-Pro.local with PID 34248 (/Users/jt/src/springframework.guru/blog/hello-world-si-activemq/target/test-classes started by jt in /Users/jt/src/springframework.guru/blog/hello-world-si-activemq)
2015-08-18 06:37:48.731  INFO 34248 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@548d708a: startup date [Tue Aug 18 06:37:48 EDT 2015]; root of context hierarchy
2015-08-18 06:37:50.166  INFO 34248 --- [           main] o.s.b.f.xml.XmlBeanDefinitionReader      : Loading XML bean definitions from URL [file:/Users/jt/src/springframework.guru/blog/hello-world-si-activemq/target/classes/spring/si-config.xml]
2015-08-18 06:37:50.442  INFO 34248 --- [           main] o.s.b.f.config.PropertiesFactoryBean     : Loading properties file from URL [jar:file:/Users/jt/.m2/repository/org/springframework/integration/spring-integration-core/4.2.0.M2/spring-integration-core-4.2.0.M2.jar!/META-INF/spring.integration.default.properties]
2015-08-18 06:37:50.452  INFO 34248 --- [           main] o.s.i.config.IntegrationRegistrar        : No bean named 'integrationHeaderChannelRegistry' has been explicitly defined. Therefore, a default DefaultHeaderChannelRegistry will be created.
2015-08-18 06:37:50.840  INFO 34248 --- [           main] faultConfiguringBeanFactoryPostProcessor : No bean named 'errorChannel' has been explicitly defined. Therefore, a default PublishSubscribeChannel will be created.
2015-08-18 06:37:50.847  INFO 34248 --- [           main] faultConfiguringBeanFactoryPostProcessor : No bean named 'taskScheduler' has been explicitly defined. Therefore, a default ThreadPoolTaskScheduler will be created.
2015-08-18 06:37:51.226  INFO 34248 --- [           main] o.s.b.f.config.PropertiesFactoryBean     : Loading properties file from URL [jar:file:/Users/jt/.m2/repository/org/springframework/integration/spring-integration-core/4.2.0.M2/spring-integration-core-4.2.0.M2.jar!/META-INF/spring.integration.default.properties]
2015-08-18 06:37:51.293  INFO 34248 --- [           main] o.s.s.c.ThreadPoolTaskScheduler          : Initializing ExecutorService  'taskScheduler'
2015-08-18 06:37:52.659  INFO 34248 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase -2147483648
2015-08-18 06:37:52.661  INFO 34248 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
2015-08-18 06:37:52.662  INFO 34248 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : Adding {service-activator:sayHelloServiceActivator} as a subscriber to the 'helloChannel' channel
2015-08-18 06:37:52.662  INFO 34248 --- [           main] o.s.integration.channel.DirectChannel    : Channel 'application:-1.helloChannel' has 1 subscriber(s).
2015-08-18 06:37:52.662  INFO 34248 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : started sayHelloServiceActivator
2015-08-18 06:37:52.662  INFO 34248 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : Adding {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel
2015-08-18 06:37:52.662  INFO 34248 --- [           main] o.s.i.channel.PublishSubscribeChannel    : Channel 'application:-1.errorChannel' has 1 subscriber(s).
2015-08-18 06:37:52.663  INFO 34248 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : started _org.springframework.integration.errorLogger
2015-08-18 06:37:52.663  INFO 34248 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 1073741823
2015-08-18 06:37:52.663  INFO 34248 --- [           main] ishingJmsMessageListener$GatewayDelegate : started org.springframework.integration.jms.ChannelPublishingJmsMessageListener$GatewayDelegate@444548a0
2015-08-18 06:37:52.839  INFO 34248 --- [           main] o.apache.activemq.broker.BrokerService   : Using Persistence Adapter: MemoryPersistenceAdapter
2015-08-18 06:37:52.947  INFO 34248 --- [  JMX connector] o.a.a.broker.jmx.ManagementContext       : JMX consoles can connect to service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi
2015-08-18 06:37:53.096  INFO 34248 --- [           main] o.apache.activemq.broker.BrokerService   : Apache ActiveMQ 5.11.1 (localhost, ID:Johns-MacBook-Pro.local-59730-1439894272895-0:1) is starting
2015-08-18 06:37:53.109  INFO 34248 --- [           main] o.apache.activemq.broker.BrokerService   : Apache ActiveMQ 5.11.1 (localhost, ID:Johns-MacBook-Pro.local-59730-1439894272895-0:1) started
2015-08-18 06:37:53.110  INFO 34248 --- [           main] o.apache.activemq.broker.BrokerService   : For help or more information please see: http://activemq.apache.org
2015-08-18 06:37:53.112  WARN 34248 --- [           main] o.apache.activemq.broker.BrokerService   : Temporary Store limit is 51200 mb, whilst the temporary data directory: /Users/jt/src/springframework.guru/blog/hello-world-si-activemq/activemq-data/localhost/tmp_storage only has 5020 mb of usable space - resetting to maximum available 5020 mb.
2015-08-18 06:37:53.164  INFO 34248 --- [           main] o.a.activemq.broker.TransportConnector   : Connector vm://localhost started
2015-08-18 06:37:53.228  INFO 34248 --- [           main] o.s.i.jms.JmsMessageDrivenEndpoint       : started helloJMSAdapater
2015-08-18 06:37:53.229  INFO 34248 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 2147483647
2015-08-18 06:37:53.243  INFO 34248 --- [           main] g.s.services.SayHelloServiceJmsIT        : Started SayHelloServiceJmsIT in 5.084 seconds (JVM running for 6.99)
################################
################################
################################
##  Hello Larry the Cable Guy!!!
################################
################################
################################
2015-08-18 06:37:56.388  INFO 34248 --- [MQ ShutdownHook] o.apache.activemq.broker.BrokerService   : Apache ActiveMQ 5.11.1 (localhost, ID:Johns-MacBook-Pro.local-59730-1439894272895-0:1) is shutting down
2015-08-18 06:37:56.388  INFO 34248 --- [       Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@548d708a: startup date [Tue Aug 18 06:37:48 EDT 2015]; root of context hierarchy
2015-08-18 06:37:56.390  INFO 34248 --- [       Thread-1] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase 2147483647
2015-08-18 06:37:56.392  INFO 34248 --- [       Thread-1] ishingJmsMessageListener$GatewayDelegate : stopped org.springframework.integration.jms.ChannelPublishingJmsMessageListener$GatewayDelegate@444548a0
2015-08-18 06:37:56.392  INFO 34248 --- [       Thread-1] o.s.i.jms.JmsMessageDrivenEndpoint       : stopped helloJMSAdapater
2015-08-18 06:37:56.392  INFO 34248 --- [       Thread-1] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase 1073741823
2015-08-18 06:37:56.392  INFO 34248 --- [       Thread-1] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase 0
2015-08-18 06:37:56.393  INFO 34248 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : Removing {service-activator:sayHelloServiceActivator} as a subscriber to the 'helloChannel' channel
2015-08-18 06:37:56.393  INFO 34248 --- [       Thread-1] o.s.integration.channel.DirectChannel    : Channel 'application:-1.helloChannel' has 0 subscriber(s).
2015-08-18 06:37:56.394  INFO 34248 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : stopped sayHelloServiceActivator
2015-08-18 06:37:56.394  INFO 34248 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : Removing {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel
2015-08-18 06:37:56.394  INFO 34248 --- [       Thread-1] o.s.i.channel.PublishSubscribeChannel    : Channel 'application:-1.errorChannel' has 0 subscriber(s).
2015-08-18 06:37:56.394  INFO 34248 --- [       Thread-1] o.s.i.endpoint.EventDrivenConsumer       : stopped _org.springframework.integration.errorLogger
2015-08-18 06:37:56.395  INFO 34248 --- [       Thread-1] o.s.c.support.DefaultLifecycleProcessor  : Stopping beans in phase -2147483648
2015-08-18 06:37:56.403  INFO 34248 --- [MQ ShutdownHook] o.a.activemq.broker.TransportConnector   : Connector vm://localhost stopped
2015-08-18 06:37:56.403  WARN 34248 --- [ter.container-1] o.s.j.l.DefaultMessageListenerContainer  : Setup of JMS message listener invoker failed for destination 'queue://hello.queue' - trying to recover. Cause: peer (vm://localhost#1) stopped.
2015-08-18 06:37:56.406  INFO 34248 --- [       Thread-1] o.s.s.c.ThreadPoolTaskScheduler          : Shutting down ExecutorService 'taskScheduler'
2015-08-18 06:37:56.413  INFO 34248 --- [MQ ShutdownHook] o.apache.activemq.broker.BrokerService   : Apache ActiveMQ 5.11.1 (localhost, ID:Johns-MacBook-Pro.local-59730-1439894272895-0:1) uptime 3.647 seconds
2015-08-18 06:37:56.414  INFO 34248 --- [MQ ShutdownHook] o.apache.activemq.broker.BrokerService   : Apache ActiveMQ 5.11.1 (localhost, ID:Johns-MacBook-Pro.local-59730-1439894272895-0:1) is shutdown

Process finished with exit code 0

Conclusion

In this Spring Framework example, I’ve shown you how easy it is to use Spring Boot to configure an Active MQ broker for use with Spring Integration. This blog post was inspired by a real world example where I was coding a enterprise service using the Spring Framework. I needed to use Spring Integration to consume messages off of a MQSeries JMS queue. MQSeries is great, but its not very light weight, nor is it appropriate for Integration tests. Thus, I wrote my integration tests to use an embedded ActiveMQ broker. You can see how easy it was to use Spring Boot to provide the ActiveMQ broker, and dependency injection to wire everything up.