비동기 메시지
어플리케이션 간에
응답을 기다리지 않고
간접적으로 메시지를 전송하는 방법
ex)
타코 클라우드 웹 사이트 ------------------> 주방
주문 데이터 전송
8.1 JMS 메시지 전송
Java Message Service
JmsTemplate 템플릿 기반의 클래스를 통해 JMS를 지원한다.
프로듀서 | 큐와 토픽에 메시지를 전송함 | |
큐 | ||
토픽 | ||
컨슈머 | 메시지를 받는다 | |
POJO plain Old Java Object | 큐, 토픽에 도착하는 메시지에 반응하여 비동기 방식으로 메시지를 받는 자바 객체 |
|
브로커 | 메시지를 전달해줌 아파치 ActiveMQ 아파치 ActiveMQ Artemis 61616 포스 리스닝 |
1. JMS 설정
브로커 스타터 의존성을 빌드에 추가한다.
<-- 브로커 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<-- 브로커 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-artemis</artifactId>
</dependency>
인증 정보
spring.artemis.host | artemis.tacocloud.com | 브로커의 호스트 |
spring.artemis.port | 61617 | 브로커의 포트 |
spring.artemis.user | tacoweb | 브로커를 사용하기 위한 사용자 |
spring.artemis.password | 13tm31n | 브로커를 사용하기 위한 사용자 암호 |
2. JmsTemplate을 사용해서 메시지 전송
JMS 스타터 의존성을 추가 --> JmsTemplate를 스프링 부트가 자동-구성 한다
없다면?
1) 베시지 브로커 연결
2) 세션 생성 코드
3) 예외 코드
JmsTemplate 메서드
send(...)
convertAndSend(...)
MessageCreator | Message 객체를 생성하기 위해 |
MessagePostProcessor | 메시지가 전송되기 전, Message의 커스터마이징 |
Destination | JMS 메시지의 도착지 메시지를 사용하는 곳 큐, 토픽 |
// send함수는 MesseageCreator mc를 매개변수로 한다.
void send(MesseageCreator mc) throws JmsException;
@service
public class JmsOrderMessagingService implements OrderMessagingService{
private JmsTemplate jms;
@Autowired
public JmsOrderMessagingService(JmsTemplate jms){
this.jms = jms;
}//생성자 함수
// 1. MesseageCreator 만드는 방법
//-> new MessageCreator() 객체 생성 -> createMessage(session)오버라이드
// order 내용 + session을 넣은 => MesseageCreator mc 객체가 전달되는 것과 같음
@Override
public void sendOrder(Order order){
jms.send(new MessageCreator(){
@Override
public Message createMessage(Session session) throws JMSException{
return session.createObjectMessage(order);
}//createMessage end
});//jms.send end
}
// 2. MesseageCreator 만드는 방법 : 람다 사용
// createMessage 생략 가능
// order 내용 + session을 넣은 => MesseageCreator mc 객체가 전달되는 것과 같음
@Override
public void sendOrder(Order order){
jms.send(session -> session.createObjectMessage(order));
}
기본 도착지 설정
spring: jms: template: dafault-destination : tacocloud.order.queue |
다른 도착지 설정
1) Destination 빈 선언 --> 메시지 전송 수행하는 빈에 주입
// Destination 빈 선언
@Bean
public Destination orderQueue(){// 아르테미스의 class다.
return new ActiveMQQueue("tacocloud.order.queue"); //목적지 : 주문.큐
}
---------------------------------------------------------------------------------------
//JmsOrderMessagingService에 주입되면
// send()를 호출할 때 이 빈을 사용하여 메시지 도착지를 지정할 수 있다
private Destination orderQueue;
@Autowired
public JmsOrderMessagingService(JmsTemplate jms, Destination orderQueue){
this.jms = jms;
this.orderQueue = orderQueue;
}
.........
@Override
public void sendOrder(Order order){
jms.send(
orderQueue,
session-> session.createObjectMessage(order));
}
// 도착지 이름 지정하는게 더 쉬움
@Override
public void sendOrder(Order order){
jms.send(
"tacocloud.order.queue",
session-> session.createObjectMessage(order));
}
Destination 객체를 사용해서
메시지 도착지를 지정하면 도착지 이름만 지정하는 것보다 다양하게 도착지를 설정할 수 있다.
메시지 변환하고 전송하기
@Override
public void sendOrder(Order order){
jms.convertAndSend("tacocloud.order.queue", order);
}
order객체는 Message 객체로 변환된 후 전송된다.
메시지 변환기 구현
Mapping잭슨2메시지변환기 (Serializable인터페이스 제약 피하기) |
잭슨 2 JSON 라이브러리를 사용해 메시지를 JSON으로 변환 |
Marshalling메시지변환기 | JAXB를 사용해 메시지를 XML로 변환 |
Messaging메시지변환기 | 받은 메시지의 메시지 변환기를 사용해 해당 메시지를 Message객체로 변환 JMS 헤더와 연관된 헤더매퍼를 표준 메시지 헤더로 변환 |
SimpleMessageConverter (기본) |
문자열을 텍스트메시지로 바이트 배열을 바이트메시지로 맵을 맵메세지로 Serializable 객체를 Object Message로 변환 |
@Bean
public MappingJackson2MessageConverter messageConverter(){
MappingJackson2MessageConverter mc = new MappingJackson2MessageConverter();
mc.setTypeIdPropertyName("_typeId");
return mc;//변환기 인스턴스 반환
}
----------------------------------------------------------------------------------
//유연하게 바꾸기
@Bean
public MappingJackson2MessageConverter messageConverter(){
MappingJackson2MessageConverter mc = new MappingJackson2MessageConverter();
mc.setTypeIdPropertyName("_typeId");//_typId 속성에 전송되는 패키지 전체 경로의 클래스 이름
Map<String, Class<?>> tims = new HashMap<String, Class<?>>();
tim.put("order", Order.class);//Order클래스를 order라는 타입ID로 매핑
mc.setTypeIdMappings(tims);//메시지 변환기 빈을 변경
// order 값이 전달된다.
// 주문 데이터가 다른 패키지에 다른 클래스 이름으로 구현 가능
return mc;//변환기 인스턴스 반환
}
'java > 스프링인액션' 카테고리의 다른 글
Spring in Action (0) | 2021.12.12 |
---|---|
10. 리액터 (0) | 2021.12.12 |
[8.3] 카프카 사용하기 (0) | 2021.12.04 |
[6.3] 스프링 데이터 REST (0) | 2021.11.27 |
[6.3] (0) | 2021.11.27 |