Tiven Wang
chevron_rightLatency chevron_rightReactive

Reactive Design Patterns - Spring Boot Messaging

Joanna Kosinska
Wang Tiven August 31, 2017
425 favorite favorites
bookmark bookmark
share share

We use Spring Boot and Spring JMS to build the messaging application.

How to setup a Spring Boot application, please refer to Spring Boot on series Try Cloud Foundry.

Basic

Dependencies

Add the dependencies:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
  <groupId>org.apache.activemq</groupId>
  <artifactId>activemq-broker</artifactId>
</dependency>

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
</dependency>

You can see the dependency tree using mvn dependency:tree:

[INFO] wang.tiven.reactivex:messaging-jms:jar:0.1.0
[INFO] +- org.springframework.boot:spring-boot-starter-activemq:jar:1.5.6.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:1.5.6.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:1.5.6.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:1.5.6.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:1.5.6.RELEASE:compile
[INFO] |  |  |  +- ch.qos.logback:logback-classic:jar:1.1.11:compile
[INFO] |  |  |  |  \- ch.qos.logback:logback-core:jar:1.1.11:compile
[INFO] |  |  |  +- org.slf4j:jcl-over-slf4j:jar:1.7.25:compile
[INFO] |  |  |  +- org.slf4j:jul-to-slf4j:jar:1.7.25:compile
[INFO] |  |  |  \- org.slf4j:log4j-over-slf4j:jar:1.7.25:compile
[INFO] |  |  +- org.springframework:spring-core:jar:4.3.10.RELEASE:compile
[INFO] |  |  \- org.yaml:snakeyaml:jar:1.17:runtime
[INFO] |  \- org.springframework:spring-jms:jar:4.3.10.RELEASE:compile
[INFO] |     +- org.springframework:spring-aop:jar:4.3.10.RELEASE:compile
[INFO] |     +- org.springframework:spring-beans:jar:4.3.10.RELEASE:compile
[INFO] |     +- org.springframework:spring-context:jar:4.3.10.RELEASE:compile
[INFO] |     |  \- org.springframework:spring-expression:jar:4.3.10.RELEASE:compile
[INFO] |     +- org.springframework:spring-messaging:jar:4.3.10.RELEASE:compile
[INFO] |     \- org.springframework:spring-tx:jar:4.3.10.RELEASE:compile
[INFO] +- org.apache.activemq:activemq-broker:jar:5.14.5:compile
[INFO] |  +- org.apache.activemq:activemq-client:jar:5.14.5:compile
[INFO] |  |  +- org.slf4j:slf4j-api:jar:1.7.25:compile
[INFO] |  |  +- org.apache.geronimo.specs:geronimo-jms_1.1_spec:jar:1.1.1:compile
[INFO] |  |  +- org.fusesource.hawtbuf:hawtbuf:jar:1.11:compile
[INFO] |  |  \- org.apache.geronimo.specs:geronimo-j2ee-management_1.1_spec:jar:1.0.1:compile
[INFO] |  \- org.apache.activemq:activemq-openwire-legacy:jar:5.14.5:compile
[INFO] \- com.fasterxml.jackson.core:jackson-databind:jar:2.8.9:compile
[INFO]    +- com.fasterxml.jackson.core:jackson-annotations:jar:2.8.0:compile
[INFO]    \- com.fasterxml.jackson.core:jackson-core:jar:2.8.9:compile

Create a message receiver

Marked the class as a Spring @Component, and marked the method who will receive the message as a @JmsListener:

import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

@Component
public class Receiver {

    @JmsListener(destination = "mailbox", containerFactory = "myFactory")
    public void receiveMessage(Email email) {
        System.out.println("Received <" + email + ">");
    }

}

Config JMS with Spring Boot

@EnableJms triggers the discovery of methods annotated with @JmsListener, creating the message listener container under the covers.

Use the Spring Boot default bean classes for JMS JmsListenerContainerFactory and MessageConverter configurations.

@SpringBootApplication
@EnableJms
public class Application {

  @Bean
  public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
                                                  DefaultJmsListenerContainerFactoryConfigurer configurer) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    // This provides all boot's default to this factory, including the message converter
    configurer.configure(factory, connectionFactory);
    // You could still override some of Boot's default if necessary.
    return factory;
  }

  @Bean // Serialize message content to json using TextMessage
  public MessageConverter jacksonJmsMessageConverter() {
    MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
    converter.setTargetType(MessageType.TEXT);
    converter.setTypeIdPropertyName("_type");
    return converter;
  }

  public static void main(String[] args) {
    // Launch the application
    ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);

    JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);

    // Send a message with a POJO - the template reuse the message converter
    System.out.println("Sending an email message.");
    jmsTemplate.convertAndSend("mailbox", new Email("info@example.com", "Hello"));
  }
}

Startup the applicaiton by mvn spring-boot:run will see in console:

Sending an email message.
Received <Email{to=info@example.com, body=Hello}>

Get the whole project source codes from Github

Dynamic Queues

Similar Posts

  • Simple Component Pattern The single responsibility principle.
  • Testing Reactive Applications How to verify that the Reactive applications you build are elastic, resilient, and responsive. Testing is covered first because of the importance of proving Reactive capabilities. Just as Test-Driven Design (TDD) allows you to ensure that you are writing logic that meets your requirements from the outset, you must focus on putting into place the infrastructure required to verify elasticity, resilience, and responsiveness.
  • Stream Processing Stream processing is a computer programming paradigm, equivalent to dataflow programming, event stream processing, and reactive programming, that allows some applications to more easily exploit a limited form of parallel processing. The stream processing paradigm simplifies parallel software and hardware by restricting the parallel computation that can be performed. Given a sequence of data (a stream), a series of operations (kernel functions) is applied to each element in the stream.
  • Reactive Design Patterns Reactive Design Patterns
  • Reactive Design Patterns - Analyzing Latency of Traditional Approach
  • Reactive Design Patterns - Reactive Manifesto 以响应式系统方式构建的系统更加灵活,松耦合和可扩展。这使得它们更容易被开发,而且经得起变化的考验。它们对于系统失败表现出显著的包容性,并且当失败真的发生时,它们能用优雅的方式去应对,而不是放任灾难的发生。响应式系统是高度灵敏的,能够给用户以有效的交互式的反馈。

Comments

comments powered by Disqus
Back to Top