- 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
)Email
is 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
MessageConverter
and associates it toJmsTemplate
andJmsListenerContainerFactory
constructed byDefaultJmsListenerContainerFactoryConfigurer
JmsTemplate
- simplifies sending messages to a Jms destination- A POJO (
Email
) object can be sent which is converted usingMessageConverter
automatically which converts it to json document
- A POJO (
JmsTempalte
andConnectionFactory
- 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=true
in application.properties or environment variable- Receiving container should also have the same settings
-
Note:
JmsTemplate
- it can receive messages through itsreceive
method- But it is synchronous (it blocks)
- Solution:
DefaultMessageListenerContainer
with cache-based connection factory- Messages can be consumed asynchronously with max connection efficiency
- Solution:
- But it is synchronous (it blocks)