스프링부트

TIL (스프링의 web layer, @EventListener, DDD, Aggregate Root, @ElementCollection, @PrePersist)

바랄 희 2022. 10. 6. 01:16

👻 스프링의 Web Layer

아키텍처 디자인 설계의 원칙

- SoC (Seperation of Concerns) 관심사 분리

- KISS (Keep It Simple Stupid) 간단하고 알기 쉽게

 

어디서 처리해야 할지 결정하고 간단하고 알기 쉽게 만들어야 함 

 

웹 어플리케이션의 관심 사항

1. 사용자 입력 처리 / 올바른 응답 반환

2. 예외처리로 용이한 에러메시지 제공

3. 트랜잭션 관리 전략

4. 인증 / 인가

5. 비지니스 로직 구현

6. 데이터 스토리지 및 기타 외부 리소스와의 통신

 

스프링부트의 3개의 Layer

1. Web Layer

- 최상단에 위치

- 외부 요청을 처리 / 올바른 응답을 반환

- 다른 레이어의 예외 처리

- 인증 관리 / 인가 확인

- 데이터 전송 객체만 처리해야 함

ex) Controller

 

2. Service Layer

- Web Layer 바로 아래에 존재 

- 트랜잭션에 대한 경계의 역할

- Controller 와 Dao 중간 영역에서 사용됨

- 데이터 전송 객체를 메소드의 매개변수로 사용 가능

- 도메인 모델 객체 처리 가능

- 데이터 전송 객체만 웹 레이어로 반환 가능

@Transactional / @Service 에 사용되는 영역

 

3. Repository layer

- 가장 낮은 계층으로 데이터 스토리지 계층과 통신하는 역할

- 직접 쿼리 호출

ex) DAO

 

DTO( Data Transfer Object)

- 데이터 저장하는 컨테이너

- 어플리케이션 계층 간의 데이터 전달에 사용됨

 

Domain Model

- 상태 비저장 클래스

- 전체 라이프 사이클동안 변경되지 않는 객체

 

전송 객체만 웹 레이어로 반환해야 하는 이유

1.보안상의 이유

도메인은 내부의 데이터베이스 구조를 노출시킬 수 있음.

클라이언트에 모델을 숨겨야 해서

 

2. 유연성의 이유

추후 도메인 모델 변경이 필요할 때 DTO 만 수정하면 되기 때문.

전송 객체가 아니라 entity나 value object 를 반환하게 되면 코드 전체를 수정해야 하는 문제 발생 가능.

 

https://lifelife7777.tistory.com/100

 

Spring Web Layer 알아보기

스프링 부트를 통해 Lombok, JPA를 활용한 간다한 CRUD API를 만드는 과정에서 Spring Web Layer에 대해 정확하게 이해하는 것이 큰 도움이 될 것 같아 Spring Web Layer를 공부해보았습니다. 그럼 시작하겠습

lifelife7777.tistory.com

 

 

👻 @EventListener

사용하는 이유

의존성이 강한 로직들의 레이어 분리

A 서비스와 B 서비스가 있다고 가정했을 때, B 서비스의 로직을 A 서비스에 녹이는 경우가 많음. 이렇게 된다면 의존성이 강해지기 때문에 이벤트 핸들러라는 레이어로 분리하고, 다시 핸들링하는 느슨한 결합 형태로 만들기 위해서 사용

즉,

A 서비스의 a 로직 -> 이벤트 발행 -> B 서비스의 b 로직

 

https://sunghs.tistory.com/139

 

[Spring] Spring의 @EventListener

Spring의 @EventListener 쓰는 이유? 의존성이 강한 로직들의 레이어를 분리할 수 있습니다. 예를 들어 A 서비스의 a 비즈니스 로직을 실행 할 때 B 서비스의 b 추가 로직을 같이 실행해야 하는 경우 A 서

sunghs.tistory.com

 

👻 DDD, Aggregate Root

DDD

Domain Driven Design 도메인 중심으로 설계하는 디자인 방법론

 

Aggregate

- 시스템이 기대하는 책임을 수행하면서 일관성을 유지하는 단위

- 명령을 수행하기 위해 함께 조회하고 업데이트해야 하는 최소 단위

- 경계를 가지기 때문에 한 애그리거트에 속한 객체는 다른 애그리거트에 속하지 않음

 

Aggregate Root

- 애그리거트에 속한 모든 객체가 정상적인 상태를 가져야 하는데 이를 일관적인 상태로 관리하는 책임을 지는 엔티티

- 일관성이 깨지지 않도록 하는 역할

- 도메인 규칙을 적용하기 위해서는 애그리거트의 외부에서 내부에 속한 객체를 직접 변경하지 않고 애그리거트 루트 엔티티의 식별자를 통해서만 접근하게 해야 함

 

잠금

비관적 잠금

- 한 번에 한 명의 사용자만 처리하도록 레코드를 독점하는 방법

- 교착 상태 발생 가능성 있음

 

낙관적 잠금

- 하나라도 변경을 하면 버전을 반드시 증가시킴

 

ex) 강의 / 수강생 엔티티가 있다면, root 인 강의 엔티티의 정원과 모집상태를 확인하고 조건이 만족된 경우에만 수강생 엔티티를 등록

 

https://eocoding.tistory.com/36

 

DDD, Aggregate Root란? + JPA CasecadeType 영속성전이

기존에 작성했던 글이지만 내용을 좀 더 보충해서 재발행한다. 우아콘2021 도메인원정대, DDD-start 책의 내용을 참고했다. 이번에 알아볼 것은, DDD란? Domain이란? Domain Layer? Domain Model? 도메인 모델링

eocoding.tistory.com

 

👻 @ElementCollectioin

컬렉션 타입의 컬럼임을 JPA 에게 알려주는 어노테이션

Embeddable Class 로 정의된 컬렉션을 테이블로 생성하여 1:N 관계를 다룸

 

@ElementCollection vs @Entity

 

 @Element Collection

- 연관된 부모 Entity 하나에만 연관되어 관리된다

- 항상 부모와 함께 저장되고 삭제되어 cascade 옵션은 제공하지 않음. 즉 cascade = ALL 인 셈

 

@Entity

- 다른 Entity에 의해 관리될 수도 있음

- join table 이나 컬럼은 ID 만으로 연관을 맺음

 

https://prohannah.tistory.com/133

 

JPA @ElementCollection

RDB에는 컬렉션과 같은 형태의 데이터를 컬럼에 저장할 수 없기 때문에, 별도의 테이블을 생성하여 컬렉션을 관리해야한다. 이때 컬렉션 객체임을 JPA에게 알려주는 어노테이션이 @ElementCollection

prohannah.tistory.com

 

👻 @PrePersist

- 엔티티의 라이프 사이클의 콜백을 조종할 수 있도록 하는 어노테이션

- 엔티티가 비영속 상태에서 영속 상태가 되는 시점 이전에 실행됨

- before persist is called for a new entity

 

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=tok0419&logNo=221599220917 

 

[Spring boot] @PrePersist 를 사용해 현재 시간을 DB에 넣어보자.

서버 구축을 하다보면 반드시 DB에 현재 시간을 저장할 일이 생긴다. 이 포스팅을 따라하면 더욱 간단하...

blog.naver.com