1. DI(Dependency Injection)를 사용해서 API 계층과 서비스 계층을 연동할 수 있다.
2. API 계층의 DTO 클래스와 서비스 계층의 엔티티(Entity) 클래스를 매핑할 수 있다.
- DI를 통한 API 계층 ↔︎ 서비스 계층 연동
✔︎ 애플리케이션에 있어 Service
는 도메인 업무 영역을 구현하는 비즈니스 로직을 처리하는 것을 의미
✔︎ 서비스 계층 서비스 클래스는 API 계층 Controller 클래스의 핸들러 메서드와 1:1 매칭
✔︎ API 계층에서 전달받은 요청 데이터를 기반으로 서비스 계층에서 비즈니스 로직을 처리하기 위해 필요한 데이터를 전달받고, 비즈니스 로직을 처리한 후 결과 값을 다시 API 계층으로 리턴해주는 역할
✔︎ @Getter
, @Setter
✔︎ @AllArgsConstructor
✔︎ @NoArgsConstructor
✔︎ Spirng에서 DI를 통해 어떤 객체를 주입받기 위해서는 주입 받는 클래스와 주입 대상 클래스 모두 Spring Bean이어야 함
✔︎ Controller 클래스에 @RestController
애너테이션을 추가하면 Spring Bean으로 등록
✔︎ Service 클래스에 @Service
애너테이션을 추가하면 Spring Bean으로 등록
✔︎ 생성자 방식의 DI는 생성자가 하나인 경우 @Autowired
애너테이션 생략 가능
- 매퍼(Mapper)를 이용한 DTO 클래스 ↔︎ 엔티티(Entitty) 클래스 매핑
✔︎ DTO 클래스와 엔티티 클래스 간 서로의 타입을 변환해주는 역할
✔︎ 매퍼 클래스에는 @Component
애너테이션을 사용해 Spring Bean으로 등록
✔︎ 매퍼 클래스를 활용한 방법
✔︎ Java Bean 규약을 지키는 객체들 간의 변환 기능을 제공하는 매퍼 구현 클래스를 자동으로 생성해주는 코드 자동 생성기
✔︎ 의존 라이브러리 설정
build.gradle
의 dependencies
에implementation 'org.mapstruct:mapstruct:1.5.3.Final
,annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.2.Final
추가✔︎ MapStruct 기반 매퍼 인터페이스 정의
@Mapper
애너테이션을 추가함으로써 해당 인터페이스를 MapStruct의 매퍼 인터페이스로 정의@Mapper
의 애트리뷰트로 componentModel = "spring"
을 지정해주면, Spring Bean으로 등록✔︎ 자동 생성된 Mapper 인터페이스 구현 클래스 확인
Gradle
의 Task
디렉토리의 build
실행해당 프로젝트명
의 build
로 들어가보면 MapperImpl
클래스 존재✔︎ Controller 클래스의 핸들러 메서드에서 MapStruct 적용
✔︎ 계층별 관심사의 분리
✔︎ 코드 구성의 단순화
✔︎ REST API 스펙의 독립성 확보
☞ DI를 통해서 앞서 배운 API 계층과 오늘 배운 서비스 계층 간의 연동을 이론적 학습과 실습을 병행했다. 또한, DTO 클래스와 엔티티 클래스를 매핑함으로써 역할 분리를 시켜주는 연습도 하였다.
Spring을 학습하면 할 때마다 Spring이 없었다면 정말 그 동안 코드들은 얼마나 복잡하고 짜기 힘들었을까 생각이 든다. (그만큼 Spring이 이해하기 어려운 내용들이 많다는 것 또한 ,,, 😂)
내일은 서비스 계층의 데이터 액세스 계층에 들어가기에 앞서 예외 처리에 관하여 학습이 잡혀 있다. 예외처리라 함은 앞서 Java를 학습하면서 배운 try-catch문과 여러 가지 Exception문들이 떠오르는데 과연 Spring에서 배우는 예외 처리는 어떨 지 기대가 된다. 내일도 달려보자 ☺️
・ 예외 처리
・ @Exceptionhandler
・ @Restcontrolleradvice