TIL

TIL 2024-02-06 EventPublisher / EventListener / 동기, 비동기

wonow_ 2024. 2. 6. 20:44

 

바위 위에서 하울링 하는 늑대가 EventPublisher

 

밑에서 듣고 어떠한 행동을 하는 늑대가 EventListener이다

 

1, 2, 3 번은 퍼블리셔의 하울링(이벤트 발행)을 듣고

 

1번 늑대는 다른 무리의 늑대여서 경계하고

2번 늑대는 같은 무리의 늑대여서 달려가고

3번 늑대는 춤춘다

 

바위 위 늑대가 1, 2, 3 번의 행동을 정해주는 것이 아니다, 들은 늑대들이 어떤 행동을 할 지 정한다. Publisher는 밑의 늑대를의 행동을 전혀 신경 쓸 필요 없이 하울링만 하면 된다.

 

    @Override
    @SwapLog
    @Transactional
    public void updatePost(Long postId, Member member, PostUpdateRequestDto requestDto) {

        log.info("updatePost - memberId: {} | memberEmail: {} | postId: {} | updateTitle: {} | updateContent: {}",
                member.getId(), member.getEmail(), postId, requestDto.title(), requestDto.content());
        Post post = findPost(postId);

        checkPostWriter(member, post);
        checkImageUrlListSize(requestDto.imageUrlList());

        applicationEventPublisher.publishEvent(new DeleteImageUrlMapEvent(post.getImageUrl()));

        List<String> imageUrlList = saveAndGetImageUrlList(requestDto.imageUrlList());

        PostMapper.updatePost(post, requestDto, createImageUrlMap(imageUrlList));
    }

 

현재 프로젝트에 작성한 메소드다

 

중간에서 applicationEventPublisher (바위 위 늑대)가 publishEvent() 메서드를 활용해 DeleteImageUrlMapEvent (하울링) 이벤트를 발행한다

 

@Getter
public class DeleteImageUrlMapEvent {

    private Map<Integer, Object> imageUrlMap;

    public DeleteImageUrlMapEvent(Map<Integer, Object> imageUrlMap) {
        this.imageUrlMap = imageUrlMap;
    }
}

 

이벤트는 이렇다 (하울링 내용)

 

    @TransactionalEventListener
    public void handleAfterCommitDeleteImageUrlMap(DeleteImageUrlMapEvent deleteImageUrlMapEvent) {
        s3ImageService.deleteImageUrlMap(deleteImageUrlMapEvent.getImageUrlMap());
    }

 

이벤트 리스너(바위 밑 늑대) 는 이 하울링을 들으면 s3ImageService 에서 deleteImageUrlMap 메서드를 사용한다.

하울링 내용은 리스너가 들어서 매개변수로 넣어준다

전역 예외 처리랑 비슷한 느낌 << 이것도 Exception이 발생하면 그 Exception을 매개변수로 받아서 e.getMessage 를 할 수 있으니

(TransactionalEventListner와 그냥 EventListner의 차이 설명은 생략)

 

여기서 알아두어야 할게 이벤트 리스너는 비동기 처리로 돌아가지는 않는 것이다.

 

@Async 를 달아야 비동기 처리가 되는데

비동기랑 동기 처리 방법에 대해서는 간략히 설명해주겠다.

 

리그오브레전드로 비유를 하자면

동기

 

EventPublisher (늑대)가 이벤트를 발행하자마자 존야(다른 행동을 할 수 없는 대기상태)를 쓴다
EventListener (춤추는 늑대였던 3번) 은 이벤트를 듣고 춤을 춘다.

3번 늑대의 춤이 다 끝나야 EventPublisher를 불렀던 메소드의 다음 행동을 한다.

 

비동기

 

위와 다르게 EventPublisher가 Event를 발행하면 3번 늑대는 춤을 춘다.

존야는 쓰지않고 EventPublisher를 불렀던 메소드의 다음 행동을 한다.

 

이해하기 쉽게 썼음~~ 이벤트 퍼블리셔랑 리스너, 비동기 처리는 유용하게 많이 쓰이는 기술이라고 함~~