- Publishing and subscribing to messages using JMS broker
JmsTemplate- used to post single message@JmsListener- used to subscribe to the message
-
Messages can be published to a POJO
-
Messages can be sent over a JMS message broker
-
Email.java
public class Email { private String to; private String body; public Email() {} public Email(String to, String body) { this.to = to; this.body = body; } // getters and setters & toString } -
Message receiver:
@Component public class Receiver { @JmsListener(destination = "mailbox", containerFactory = "myFactory") public void receiveMessage(Email email) { System.out.println("Received <" + email + ">"); } }JmsListener- definesDestination- name of destination, the method should listen toJmsListenerContainerFactory- reference to this which is used to construct message listener container- Optional
- Used to customize container (Spring boot registers a default factory)
- Optional
-
Application.java
@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 reuses the message converter System.out.println("Sending an email message."); jmsTemplate.convertAndSend("mailbox", new Email("info@example.com", "Hello")); } }@EnableJms(M)- Triggers discovery of methods annotated with
@JmsListener(M)
- Triggers discovery of methods annotated with
DefaultJmsListenerContainerFactoryConfigurer- provided by bootJmsMessageListenerContainer- will be identical to the one boot constructs by default
MessageConverter- it can convert only basic types (String,Map,Serialize)Emailis not made serializable- We want to use Jackson and serialize content to json in text format
TextMessage
- We want to use Jackson and serialize content to json in text format
- Spring boot will detect default
MessageConverterand associates it toJmsTemplateandJmsListenerContainerFactoryconstructed byDefaultJmsListenerContainerFactoryConfigurer JmsTemplate- simplifies sending messages to a Jms destination- A POJO (
Email) object can be sent which is converted usingMessageConverterautomatically which converts it to json document
- A POJO (
JmsTempalteandConnectionFactory- not explicitly defined- Generated automatically by Spring boot
- ActiveMQ broker runs embedded - by default
- Messages are transmitted to queues by having pubSubDomain set to false
JmsMessageListenerContainer- is configured the same- Customization:
spring.jms.isPubSubDomain=truein application.properties or environment variable- Receiving container should also have the same settings
-
Note:
JmsTemplate- it can receive messages through itsreceivemethod- But it is synchronous (it blocks)
- Solution:
DefaultMessageListenerContainerwith cache-based connection factory- Messages can be consumed asynchronously with max connection efficiency
- Solution:
- But it is synchronous (it blocks)