API 계층에서 전달받은 클라이언트의 요청 데이터를 기반으로 실질적인 비즈니스 요구사항을 처리하는 계층
Controller 클래스와 Service 클래스가 메서드 호출을 통해 상호작용하는 것
1. Service 클래스 작성
Service 클래스 : 도메인 업무 영역을 구현하는 비즈니스 로직을 처리하는 곳
먼저 Controller 의 핸들러 메서드가 전달받은 요청을 실제로 처리하는 메서드를 1:1 로 매칭해 생성

createMember() 메서드와 updateMember() 메서드의 파라미터 Member 타입은 도메인 엔티티(Entity) 클래스!

데이터 엑세스 계층과 연동 전이기 때문에,
임시로 Member 객체를 그대로 리턴하거나 Stub 데이터를 넘겨준다!
2. Entity 클래스 작성
도메인 엔티티(Entity) 클래스 : 서비스 계층에서 데이터 액세스 계층과 연동하면서 비즈니스 로직을 처리하기 위해 필요한 데이터를 담는 역할

API 계층의 Dto 클래스에서 사용한 멤버 변수들이 모두 포함된다!
@AllArgsConstructor과 @NoArgsConstructor 함께 사용
클래스에 필요한 모든 매개변수를 받는 생성자와 매개변수가 없는 기본 생성자를 자동으로 생성할 수 있어, 객체의 생성과 초기화가 간편하다!
new 키워드로 해당 클래스의 객체를 생성하여, 해당 객체로 클래스의 메서드를 호출해서 사용하는 방법 > 강한 결합(Tight Coupling)
new 키워드로 Service 클래스의 객체 생성
MemberController 에서 MemberService 를 사용하기 위해 MemberController 의 생성자 내부에서 new 키워드를 사용하여 MemberService 의 객체를 생성


Spring의 DI를 사용하여 클래스 간 느슨한 결합(Loose Coupling)

MemberController 생성자 파라미터로 MemberService 객체를 주입(Injection) 했다!
그런데, Spring 에서 DI 적용 시 대상 클래스가 모두 Spring Bean 이어야 하기 때문에 Service 클래스에 @Service 추가.

(** 생성자가 하나 이상일 경우, 생성자에 반드시 @Autowired 애너테이션 추가)
5. Mapper 클래스 작성
DTO 클래스와 엔티티(Entity) 클래스를 서로 변환해 주는 역할

핸들러 메서드의 return 값이 될 응답 데이터 DTO 클래스




도메인 별 매퍼 클래스를 만드는건 비효육적
MapStruct 가 매퍼 클래스를 자동으로 구현하여 개발자의 생성성 향상
DTO 클래스처럼 Java Bean 규약을 지키는 객체들 간의 변환 기능을 제공하는 매퍼(Mapper) 구현 클래스를 자동으로 생성해 주는 코드 자동 생성기
dependencies {
...
...
implementation 'org.mapstruct:mapstruct:1.4.2.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
}
build.gradle 파일에 위 의존 라이브러리 추가 후 Gradle 프로젝트를 reload

@Mapper : MapStruct의 매퍼 인터페이스로 정의componentModel = "spring" 애트리뷰트 : Spring의 Bean으로 등록이제 Gradle의 build task를 실행하면, Mapper 인터페이스의 구현 클래스가 build 디렉토리 내 Mapper 인터페이스가 위치한 패키지 안에 생성된다.
//import com.codestates.member.mapper.MemberMapper;
import com.codestates.member.mapstruct.mapper.MemberMapper; // 패키지 변경
사용하고자 하는 매퍼(Mapper)와 Controller URI의 버전 번호만 변경해주면 끝!
⭐ DTO 클래스와 엔티티 클래스의 역할 분리가 필요한 이유
- 사용되는 계층이 달라, 쓰임도 다르다.
- DTO : API 계층에서 요청 데이터를 받고, 응답 데이터를 주는 목적
- Entity : 서비스 계층에서 데이터 엑세스 계층과 연동해 비즈니스 로직의 결과로 생성된 데이터를 다루는 목적
- 코드 구성의 단순화
- DTO로 원하는 데이터만 제공할 수 있어 REST API 스펙의 독립성 확보