Spring/JPA

태태개발일지(EVENT)

태태코 2023. 12. 4. 15:18
반응형

서비스 로직을 처리할 때 하나의 로직 이후에 연계되어서 일어나는 로직을 실행할 때, 하나의 도메인 서비스에 다른 도메인 서비스를 넣어서 강력한 결합을 사용하고 있었다.

 

ex)

@Service
@Slf4j
@RequiredArgsConstructor
public class PostService {
    private final PostRepository repository;
    private final MessageRepository messageRepository;

}

이런 것을 해결하기 위해서 중간에 event publisher를 둠으로써 결합의 강도를 줄일 수 있는 event를 알게되었다.

 

 


@Entity
@Table(name = "post")
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Getter
@Setter
@Builder
public class Post extends AbstractAggregateRoot<Post> {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private String content;

   public Post publish(){
       this.registerEvent(new PostPublishedEvent((this)));
       return this;
   }

    public static PostResponseDto entityToResponseDto(Post post){
        return PostResponseDto.builder()
                .id(post.getId())
                .name(post.getName())
                .content(post.getContent())
                .build();
    }
}

 

우선 POST객체안에  AbstractAggregateRoot<Post>를 상속받아서 이벤트를 일으키는 메서드를 생성한다.

 


public class PostPublishedEvent extends ApplicationEvent {

    private final Post post;
    public PostPublishedEvent(Object source) {
        super(source);
        this.post=(Post) source;
    }

    public Post getPost() {
        return post;
    }
}

 

이벤트가 생성되었을 시 출간할 이벤트를 저장한다.


@RequiredArgsConstructor
@Component
public class PostListener  {

    private final MessageRepository messageRepository;

    @EventListener
    public void onApplicationEvent(PostPublishedEvent event) {
        System.out.println("------------------------");
        System.out.println(event.getPost().getName()+"is publish");
        messageRepository.save(
                Message.builder().content(event.getPost().getContent()).build()
        );
        System.out.println("------------------------");

    }
}

 

이벤트가 발생하였을 경우 그 이벤트 PUBLISHER를 통해 받아서 어떤 로직을 처리할 까 구현하는 Listener 이다.


@Service
@Slf4j
@RequiredArgsConstructor
public class PostService {
    private final PostRepository repository;

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    public Post enrollPost(Post post){
        log.info("PostServie: enrollPost exec");
        applicationEventPublisher.publishEvent(post.publish());
        return repository.save(post);
    }
}

 

ApplicationEventPublisher를 통해서 Post가 Save되거나 다른 로직이 실행되었을 때 이벤트를 발생시킨다.

그를 통해서 Listener가 그 이벤트를 받아서 새로운 로직을 처리한다.

 

    @EventListener
    public void onApplicationEvent(PostPublishedEvent event) {
        System.out.println("------------------------");
        System.out.println(event.getPost().getName()+"is publish");
        messageRepository.save(
                Message.builder().content(event.getPost().getContent()).build()
        );
        System.out.println("------------------------");

    }

이 코드를 보면 PostService에서 MessageService를 불러서 처리하는 것이아닌 EventListener에서 처리하기 때문에 결합도가 낮아졌다고 할 수 있다.

이러한 효율적인 것은 열심히 도입해서 향상성을 높힐 것이다.

반응형

'Spring > JPA' 카테고리의 다른 글

태태개발일지 - JPA 연관관계  (0) 2024.11.14
태태개발일지 - JPA Auditing  (2) 2024.10.22
태태개발일지(query method)  (0) 2023.08.21
태태개발일지(연관관계 JPA)  (0) 2023.08.17
태태개발일지(JPA트러블 슈팅)  (0) 2023.08.16