코드 작성

  1. gradle에 의존성 추가
// spring cloud stream
implementation 'org.springframework.cloud:spring-cloud-starter-stream-rabbit'
implementation 'org.springframework.boot:spring-boot-starter-amqp'
  1. application.yml에 속성 추가
spring:
 cloud:
    stream:
      bindings:
        paperViewOutput:
          destination: paperViewCountTopic
        paperDownloadOutput:
          destination: paperDownloadCountTopic
        itemViewOutput:
          destination: itemViewCountTopic
  1. 이벤트 생성 (지금은 DB insert용)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
public class PaperViewEvent {
    private Integer paperSn;
    private String ipAddress;
    private Paper paper;
}
  1. EventSource 생성
public interface PaperEventSource {

    String PAPER_VIEW_OUTPUT = "paperViewOutput";
    String PAPER_DOWNLOAD_OUTPUT = "paperDownloadOutput";
    String ITEM_VIEW_OUTPUT = "itemViewOutput";

    @Output(PAPER_VIEW_OUTPUT)
    MessageChannel paperViewOutput();

    @Output(PAPER_DOWNLOAD_OUTPUT)
    MessageChannel paperDownloadOutput();

    @Output(ITEM_VIEW_OUTPUT)
    MessageChannel itemViewOutput();
}
  1. consumer 생성
@EnableBinding(PaperEventSource.class)
@RequiredArgsConstructor
public class PaperEventConsumer {

    private final PaperRepository paperRepository;

    @StreamListener(target = PaperEventSource.PAPER_VIEW_OUTPUT)
    public void handlePaperViewEvent(PaperViewEvent event) {
        event.setPaper(paperRepository.findPaperByPaperSn(event.getPaperSn()));
        // Insert Logic here
        System.out.println("insert here");
    }

    @StreamListener(target = PaperEventSource.PAPER_DOWNLOAD_OUTPUT)
    public void handlePaperDownloadEvent(Integer paperSn) {
        // Insert Logic here
    }

    @StreamListener(target = PaperEventSource.ITEM_VIEW_OUTPUT)
    public void handleItemViewEvent(Integer paperSn) {
        // Insert Logic here
    }
}
  1. message 요청
@GetMapping("/detail/{paperSn}")
public ResponseEntity<ResponseDto<PaperViewResponseDto>> detail(
        @Parameter(name = "paperSn", description = "논문 순번", required = true) @PathVariable Integer paperSn
        , HttpServletRequest request
) {
    PaperViewResponseDto response = paperCmmnService.getPaperDetail(paperSn);

    // paper 조회수 증가시키는 message 요청
    PaperViewEvent event = PaperViewEvent.builder()
            .paperSn(paperSn)
            .ipAddress(request.getRemoteAddr())
            .build();
    paperEventSource.paperViewOutput().send(MessageBuilder.withPayload(event).build());

    return ResponseEntity.ok().body(
            ResponseDto.<PaperViewResponseDto>builder()
                    .data(response)
                    .message("success")
                    .build()
    );
}

실행 순서

<aside> 1️⃣ 요청 수신

</aside>

<aside> 2️⃣ 이벤트 생성

</aside>

PaperViewEvent event = PaperViewEvent.builder()
            .paperSn(paperSn)
            .ipAddress(request.getRemoteAddr())
            .build();