Spring Boot JMS | සිංහලෙන් JMS Message Service ඉගෙන ගමු | SC Guide

Spring Boot JMS Integration SC Guide
ආයුබෝවන් කට්ටියට! කොහොමද ඉතින්? අද අපි කතා කරන්න යන්නේ ගොඩක් වැදගත්, ඒ වගේම අපේ Software Development ගමනට අලුත් Dimension එකක් එකතු කරන මාතෘකාවක් ගැන – ඒ තමයි Spring Boot එක්ක JMS (Java Message Service) Implement කරන විදිහ.
දැන් ඔයාලා හිතනවා ඇති මොකක්ද මේ JMS කියන්නේ කියලා? සරලවම කිව්වොත්, ඒක Java Applications අතර messages send කරන්නයි, receive කරන්නයි පුළුවන් API එකක්. පොඩි Business Applications වල නම් ඒක එච්චරම ඕනේ නැති වෙන්න පුළුවන්. හැබැයි අපි Scalable, Distributed Systems හදනකොට JMS වගේ Message Queues නැතුව බෑ. හිතන්නකෝ ඔයාලගේ System එකේ Customers ලා මිලියන ගාණක් ඉන්නවා කියලා. එක පාරටම ඕගොල්ලන්ගේ Website එකට Orders දහස් ගාණක් ආවොත්, ඒ හැම Order එකක්ම එක පාරටම Process කරන්න හැදුවොත් System එක Slow වෙන්න පුළුවන්, නැත්නම් Crash වෙන්නත් පුළුවන්. එතකොට තමයි JMS වගේ Message Queues අපිට පිහිටට එන්නේ. අපි Messages Queue එකකට දානවා, System එකේ Back End එකේ Process වෙනවා. ඒක හරියට බැංකුවක පෝලිමක් වගේ, හැමෝටම එක පාරට සේවය දෙන්නේ නෑ, පෝලිමේ ඉන්න අනුපිළිවෙලට තමයි සේවය දෙන්නේ.
ඇයි Spring Boot එක්ක JMS?
Spring Boot කියන්නේ අපේ වැඩ ගොඩක් ලේසි කරන Framework එකක්නේ. JMS Integrate කරන එකත් Spring Boot එක්ක පුදුම තරම් ලේසියි. Minimal Configuration වලින් අපිට JMS Setup කරගන්න පුළුවන්. Spring Boot ගේ Auto-configuration, Dependency Injection, Template වගේ Features නිසා Message Producer, Consumer Implement කරන එකත් ලේසි වෙනවා. ඉතින්, කම්මැලි නැතුව අපි බලමු කොහොමද මේක කරන්නේ කියලා!
1. Project එක Setup කරගමු! (Setup the Project)
මුලින්ම අපි Spring Boot Project එකක් හදමු. Spring Initializr (start.spring.io) පාවිච්චි කරලා Project එකක් හදාගන්න. Dependencies විදිහට මේ ටික add කරගන්න:
- Spring Web (REST API එකක් හදන්න)
- Spring for JMS (JMS support එකට)
- ActiveMQ Artemis (අපේ Message Broker එක විදිහට) - ActiveMQ කියන්නේ Popular Open Source Message Broker එකක්. අපිට Local එකේ Test කරන්න මේක පාවිච්චි කරන්න පුළුවන්.
Maven (pom.xml) Dependencies ටික මේ වගේ වෙයි:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
දැන් අපි application.properties
එකේ ActiveMQ connection එක configure කරගමු:
# ActiveMQ configuration
spring.activemq.broker-url=tcp://localhost:61616
spring.activemq.user=admin
spring.activemq.password=admin
# Enable JMS to use a POJO as a message converter
spring.jms.pub-sub-domain=true # For Topics (false for Queues by default)
සාමාන්යයෙන් Spring Boot Auto-configuration එක නිසා අපිට මේ ටික විතරක් ඇති. හැබැයි පොඩි Customization එකක් ඕන නම් අපි JmsTemplate
එකට MessageConverter
එකක් Define කරමු. මේකෙන් අපිට Object එකක් Direct Messages විදිහට යවන්න පුළුවන්.
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.support.converter.MappingJackson2MessageConverter;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessageType;
import javax.jms.ConnectionFactory;
@Configuration
public class JmsConfig {
@Bean
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory);
// You can add more configurations here, e.g., transaction management
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;
}
}
මේ JmsConfig
Class එකේ අපි MappingJackson2MessageConverter
එකක් Define කරලා තියෙනවා. මේකෙන් වෙන්නේ Java Object එකක් JSON විදිහට Convert වෙලා Message එකක් විදිහට යන එක. ඒ වගේම myFactory
කියන Bean එකෙන් අපිට Custom JmsListenerContainerFactory
එකක් Define කරන්න පුළුවන්. මේකෙන් අපිට Consumer ගේ behaviours (උදා: Concurrency, error handling) වෙනස් කරන්න පුළුවන්.
2. Message එකක් Send කරමු! (Sending a Message)
Message එකක් Send කරන්න අපි JmsTemplate
එක පාවිච්චි කරනවා. මේක Spring Boot ගේ Auto-configuration එකෙන් අපිට Inject කරගන්න පුළුවන්.
මුලින්ම අපි Simple Data Class එකක් හදාගමු, මේක තමයි අපේ Message Payload එක වෙන්නේ:
import java.io.Serializable;
public class MyMessage implements Serializable {
private String sender;
private String content;
// Constructors, Getters, Setters
public MyMessage() {}
public MyMessage(String sender, String content) {
this.sender = sender;
this.content = content;
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public String toString() {
return "MyMessage{" +
"sender='" + sender + '\'' +
", content='" + content + '\'' +
'}';
}
}
දැන් අපි JmsTemplate
එක පාවිච්චි කරලා Message එකක් Send කරන Service එකක් හදමු:
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;
@Service
public class MessageSender {
private final JmsTemplate jmsTemplate;
public MessageSender(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
public void sendMessage(String destination, MyMessage message) {
System.out.println("Sending message to " + destination + ": " + message);
jmsTemplate.convertAndSend(destination, message);
}
}
convertAndSend
method එකෙන් වෙන්නේ අපේ MyMessage
Object එක MessageConverter
එක පාවිච්චි කරලා JMS Message එකක් විදිහට Convert කරලා Destination (Queue or Topic) එකට යවන එක.
මේක Test කරන්න අපි Simple REST Controller එකක් හදමු:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MessageController {
private final MessageSender messageSender;
public MessageController(MessageSender messageSender) {
this.messageSender = messageSender;
}
@GetMapping("/send")
public String sendMessage(@RequestParam String sender, @RequestParam String content) {
MyMessage message = new MyMessage(sender, content);
messageSender.sendMessage("myQueue", message); // "myQueue" is the destination name
return "Message sent to myQueue: " + message;
}
}
දැන් අපිට Browser එකේ http://localhost:8080/send?sender=Kasun&content=Hello_JMS
වගේ ගහලා Message එකක් Send කරන්න පුළුවන්.
3. Message එකක් Receive කරමු! (Receiving a Message)
Message එකක් Receive කරන්න Spring JMS ගේ @JmsListener
Annotation එක ගොඩක් පහසුයි. මේකෙන් අපිට Method එකක් Define කරලා ඒ Method එක Message එකක් ආවම Execute වෙන්න සලස්වන්න පුළුවන්.
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
@Component
public class MessageReceiver {
@JmsListener(destination = "myQueue", containerFactory = "myFactory")
public void receiveMessage(MyMessage message) {
System.out.println("Received <" + message + ">");
// Process the message here, e.g., save to database, send email etc.
}
}
මෙහිදී, destination = "myQueue"
කියන්නේ අපි listen කරන Queue එක. containerFactory = "myFactory"
කියන්නේ අපේ Custom JmsListenerContainerFactory
එක පාවිච්චි කරන එක. මේක දාන්නේ නැතුවත් වැඩ කරනවා, හැබැයි Custom Configuration (උදා: concurrency) ඕන නම් මේක වැදගත්.
දැන් ඔයාලා Application එක Run කරලා http://localhost:8080/send?sender=Kasun&content=Hello_JMS
කියලා ගහලා බලන්න. Console එකේ Received <MyMessage{sender='Kasun', content='Hello_JMS'}>
වගේ Message එකක් Print වෙන්න ඕනේ.
4. Queues vs. Topics: මොකක්ද වෙනස? (Queues vs. Topics: What's the Difference?)
JMS වල ප්රධාන Concepts දෙකක් තියෙනවා: Queues (Point-to-Point) සහ Topics (Publish-Subscribe).
- Queues: මේක Point-to-Point communication එකක්. Message එකක් Queue එකකට දැම්මම, ඒක එක Consumer කෙනෙක්ට විතරයි Receive කරන්න පුළුවන්. හරියට Letter Box එකක් වගේ. එක Letter එකක් එක කෙනෙක්ට විතරයි කියවන්න පුළුවන්. Order Processing වගේ දේවල් වලට මේක ගොඩක්ම සුදුසුයි. (Default behaviour of Spring JMS)
- Topics: මේක Publish-Subscribe communication එකක්. Message එකක් Topic එකකට දැම්මම, ඒක Listen කරන හැම Consumer කෙනෙක්ටම Message එකේ Copy එකක් Receive කරන්න පුළුවන්. හරියට TV Channel එකක් වගේ. එක Broadcast එකක් හැමෝටම බලන්න පුළුවන්. News Feeds, Stock Price Updates වගේ Real-time Data Sharing වලට මේක සුදුසුයි.
Topic එකක් පාවිච්චි කරන්න නම්, application.properties
එකේ spring.jms.pub-sub-domain=true
කියලා දාන්න ඕනේ. ඒ වගේම MessageSender
සහ MessageReceiver
වල destination
එක වෙනස් කරන්න පුළුවන් (උදා: "myTopic").
5. වැදගත් Tips සහ Best Practices (Important Tips and Best Practices)
JMS Implement කරනකොට මේ දේවල් මතක තියාගන්න එක ගොඩක් වැදගත්:
- Error Handling: Messages Process කරනකොට Errors එන්න පුළුවන්.
@JmsListener
method එක ඇතුලේtry-catch
Blocks දාලා Errors Handle කරන්න. Failed Messages Retry කරන එක ගැනත් හිතන්න (Dead Letter Queues - DLQ). - Transactions: Business Operations වලදී Messages යවන එක සහ Database Transactions එකටම සිද්ධ වෙන්න ඕනේ නම්, Spring ගේ Transaction Management පාවිච්චි කරන්න පුළුවන්.
@Transactional
Annotation එක JMS operations එක්ක පාවිච්චි කරන්න පුළුවන්. - Message Converters: අපි
MappingJackson2MessageConverter
එක පාවිච්චි කළා වගේ, ඔයාලට Custom Converters හදන්න පුළුවන්. මේකෙන් අපේ Java Objects Messages විදිහට Convert කරන එක ගොඩක් ලේසි වෙනවා. - Concurrency:
DefaultJmsListenerContainerFactory
එක Configure කරලාconcurrency
property එකෙන් එක පාරට Process කරන්න පුළුවන් Messages ගාන regulate කරන්න පුළුවන්. මේක Application එකේ Performance එකට ගොඩක් වැදගත්. - Durable Subscriptions (for Topics): Topic එකකට subscribe වෙන Consumer කෙනෙක් offline වුණොත්, ආයේ online ආවම එයාට missed messages receive වෙන්න ඕනේ නම්, Durable Subscription පාවිච්චි කරන්න වෙනවා. මේකට Consumer ID එකක් specify කරන්න ඕනේ.
නිගමනය (Conclusion)
ඉතින් යාලුවනේ, ඔයාලට අද Spring Boot එක්ක JMS Implement කරන හැටි ගැන හොද අවබෝධයක් ලැබෙන්න ඇති කියලා හිතනවා. Message Queues කියන්නේ Scalable, Reliable, Distributed Systems හදනකොට නැතුවම බෑ වගේ දෙයක්. Spring Boot නිසා මේ වගේ Complex Concepts වුණත් ලේසියෙන් Implement කරන්න පුළුවන් වෙලා තියෙනවා.
මේ Concepts තව දුරටත් Explore කරන්න, ඔයාලගේ Projects වලට මේක Integrate කරලා බලන්න. මොකද, Practice කරන තරමට තමයි අපි Skillful වෙන්නේ.
මේ ගැන ඔයාලට මොනවා හරි ප්රශ්න තියෙනවා නම්, නැත්නම් මේ වගේ තවත් මොනවා හරි Topic එකක් ගැන දැනගන්න ඕනේ නම්, පහලින් Comment එකක් දාන්න අමතක කරන්න එපා. මම උත්තර දෙන්නම්! එහෙනම්, තවත් අලුත් Technical Article එකකින් හමුවෙමු! Stay tuned and keep coding!
ජය වේවා!