관리 메뉴

개발하는 동그리

[Spring] Spring MVC - 서비스 계층 본문

IT 정보/Spring

[Spring] Spring MVC - 서비스 계층

개발하는 동그리 2022. 7. 4. 12:08
반응형

학습 내용

  • Spring DI를 이용해서 API 계층과 비지니스 계층을 연동
  • API 계층에서 DTO 객체를-> 비지니스 계층 도메인 Enttiy 객체로 변환

MemberService 클래스

  • @Service 애너테이션 사용 ( 자동 Spring bean 등록 )
  • MemberService 클래스에 HandlerMethod가 전달받은 요청을 처리하는 메서드를 작성 
  • Handler Method와 1대1로 매치
  • createMember() , updateMember() 메서드에 파라미터와 리턴값에 Member타입 사용

Member 클래스

  • DTO는  API계층에서 클라이언트의 RequestBody를 전달 받고 클라이언트에게 돌려줄 응답 데이터를 담는 역할이라면, Member클래스는 API계층에서 전달받은 요청 데이터를 기반으로 서비스 계층에서 비지니스 로직을 처리하기 위한 데이터를 전달받고, 비지니스 로직을 처리한 후 API 계층으로 리턴하는 역할
  • 데이터 엑세스 계층과 연동, 비지니스 로직 처리에 필요한 데이터를 담는 클래스 = 도메인 엔티티 클래스
  • 멤버변수는 postDto , PatchDto 클래스에 사용하는 모든 멤버 변수
  • @AllArgConstructor : 모든 멤버 변수를 파라미터로 가지는 생성자
  • @NoArgConstructor : 파라미터가 없는 생성자
  • @Getter / @Setter 

MemberController에서 MemberService 기능 사용

  • 전체 코드
public class MemberController {
    private final MemberService memberService;

    public MemberController() {
        this.memberService = new MemberService(); 
    }

    @PostMapping
    public ResponseEntity postMember(@Valid @RequestBody MemberPostDto memberDto) {
				
        Member member = new Member();
        member.setEmail(memberDto.getEmail());
        member.setName(memberDto.getName());
        member.setPhone(memberDto.getPhone());

				
        Member response = memberService.createMember(member);

        return new ResponseEntity<>(response, HttpStatus.CREATED);

 

  • MemberController 클래스에서 MemberService 객체 생성 (동시에 DI 주입) - 스프링기능!
  public MemberController(MemberService memberService) {
        this.memberService = memberService;

 

  • MemberPostDto 클래스 정보를 Member클래스에 채워 넣음
        Member member = new Member();
        member.setEmail(memberDto.getEmail());
        member.setName(memberDto.getName());
        member.setPhone(memberDto.getPhone());

 

  • ⭐⭐서비스 계층과 연결 ⭐⭐
Member response = memberService.createMember(member);

        return new ResponseEntity<>(response, HttpStatus.CREATED);

 

매퍼(Mapper)

  • DTO클래스와 <-> Entity 클래스 매핑
  • Handler Method가 Entity 클래스의 객체로 클라이언트에게 응답하는 것을 보완하기 위한 계층간의 분리
    • DTO 클래스 -> Entity 클래스 변환을 다른 클래스에게 위임 ( 그 주인공 => Mapper )
@Component  
public class MemberMapper {
		// MemberPostDto를 Member로 변환
    public Member memberPostDtoToMember(MemberPostDto memberPostDto) {
        return new Member(0L,
                memberPostDto.getEmail(), 
                memberPostDto.getName(), 
                memberPostDto.getPhone());
    }

		// MemberPatchDto를 Member로 변환
    public Member memberPatchDtoToMember(MemberPatchDto memberPatchDto) {
        return new Member(memberPatchDto.getMemberId(),
                null, 
                memberPatchDto.getName(), 
                memberPatchDto.getPhone());
    }

    // Member를 MemberResponseDto로 변환
    public MemberResponseDto memberToMemberResponseDto(Member member) {
        return new MemberResponseDto(member.getMemberId(),
                member.getEmail(), 
                member.getName(), 
                member.getPhone());
    }
}
  • @Component 애너테이션을 이용해서 Bean 등록!
  • MemberPatchDto -> member
  • MemberPostDto -> member
  • member -> MemberResponseDto 
  • 응답용 클래스 MemberResponseDto 생성

 

MapStruct

  • Mapper 클래스를 일일이 만드는 것은 비효율적!!
  • MapStruct가 Mapper를 자동 생성 (편리~)
  • build.gradle 추가
dependencies {
	...
	implementation 'org.mapstruct:mapstruct:1.4.2.Final'
	annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
}
  • MapperInterface 생성, 정의
    • @Mapper 애너테이션을 통해 MapStruct의 매퍼 인터페이스로 정의
    • 어트리뷰트를 통해 component = "spring" 지정 = bean 등록!!
    • 구현 클래스는 gradle -> build 실행하면 자동으로 생성된다
@Mapper(componentModel = "spring")  
public interface MemberMapper {

    Member memberPostDtoToMember(MemberPostDto memberPostDto);
    Member memberPatchDtoToMember(MemberPatchDto memberPatchDto);
    MemberResponseDto memberToMemberResponseDto(Member member);
    
}

 

DTO 클래스와 Entity 클래스의 역할 분리 이유

  • 계층별 관심사 분리 
    • 하나의 클래스나 메서드가 여러개의 기능을 구현하는것은 좋지 않다
  • 코드 구성의 단순화
    • Entity 클래스에서 유효성 검사를 하면 유지보수가 어려워진다. 
  • REST API 스펙의 독립성
    • 데이터 엑세스 계층에서 받은 데이터로 채워진 Entity 클래스를 응답으로 전달할 경우 원치않는 데이터까지 전달할 가능성이 있다. 
    • 따라서 DTO 클래스를 이용해서 원하는 정보만 제공 가능
반응형

'IT 정보 > Spring' 카테고리의 다른 글

[Spring] JUnit Test 기능  (18) 2022.07.12
[Spring] Spring MVC - 예외 처리  (38) 2022.07.04
[Spring] Spring MVC - API 계층  (6) 2022.07.04
[Spring] Spring MVC - 데이터 엑세스 계층(1) JDBC  (15) 2022.06.30
[Spring] AOP 기본 개념  (47) 2022.06.21