[41일차]서비스 계층 연동, 매퍼(Mapper)

유태형·2022년 6월 27일
0

코드스테이츠

목록 보기
41/77

오늘의 목표

  1. 서비스 계층 연동
  2. 매퍼(Mapper)



내용

서비스 계층 연동

서버의 구조는 API 계층, 서비스 계층, 데이터 접근 계층으로 3층의 구조로 계층화 되어 있습니다. 계층간에도 데이터 전달이 필요합니다.

API계층을 구현한 @Controller클래스와 서비스계층을 구현한 @Service클래스가 메서드 호출로 상호작용 합니다.



Service 클래스

@Controller 클래스를 기반으로 @Service클래스의 큰 틀을 만들 수 있습니다.

@Service
public class 서비스클래스{
	public 엔티티클래스 서비스메서드(엔티티클래스 매개변수){
    	//비즈니스 로직
    }
    ...
}
  • @Service : 서비스 클래스를 스프링 빈 객체로 관리합니다.
  • 엔티티클래스 : API계층에서 전달 받은 요청 데이터를 기반으로 서비스 계층에게 전달하고, 서비스계층에서 비즈니스 로직 처리후 결과를 다시 API계층에게 전달하는 역할을 수행하는 클래스입니다.


엔티티 클래스

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class 엔티티{
	필드1
    필드2
    필드3
    ...
}

엔티티 클래스는 DTO클래스와 마찬가지로 단순히 값만 전달하는 객체이므로 로직을 처리하는 메서드가 존재하지 않습니다.

Lombok의 에너테이션

  • @Getter : 클래스내에 필드들의 Getter메서드를 자동으로 생성합니다.
  • @Setter : 클래스내에 필드들의 Setter메서드를 자동으로 생성합니다.
  • @NoArgsConstructor : 매개변수가 없는 생성자(기본 생성자)를 생성합니다.
  • @AllArgsConstructor : 모든 필드를 매개변수로 가지는 생성자를 생성합니다.
  • @RequiredArgsConstructor : final 상수, @NonNull 필드만 매개변수로 가지는 생성자를 생성합니다.


@Controller에서 @Service 클래스 DI

컨트롤러 클래스에서 서비스 클래스를 이용하기 위해선 객체지향의 객체.메서드()형식의 메서드 호출이 필요합니다. 스프링에선 스프링 컨테이너가 빈 객체들을 자동으로 생성하고 의존주입까지 담당하고 있습니다. @Controller와 @Service에너테이션 모두 @Component에너테이션을 내장하고 있으므로 빈 객체로써 관리되고 스프링 컨테이너에 의한 의존주입이 가능합니다.

@RestController
@RequestMapping("공통URL")
@Validated
public class 컨트롤러{
	private final 서비스클래스 서비스;
    
    public 컨트롤러(서비스클래스 서비스){
    	this.서비스 = 서비스;
    }
    
    @PostMapping("URI")
    public ResponseEntity 핸들러메서드(@Valid @RequestBody DTO클래스 dto){
    	
        DTO클래스 resposne = 서비스.메서드(dto);
        return new ResponseEntity<>(resposne.HttpStatus.CREATED);
    }
    @GetMapping("")
    @PatchMapping
    @DeleteMapping
    ...
}

생성자 주입을 통하여 컨트롤러 클래스에 서비스 클래스를 의존 주입합니다. 의존 주입 DI를 하게 되면 컨트롤러 객체에서 서비스 객체의 메서드를 이용할 수 있게 되므로 비즈니스 로직에 접근할 수 있게 됩니다.




매퍼(Mapper)

유지보수, 수정등을 수행할 때 만약 모든 계층에서 사용할 클래스를 사용한다면 매우 복잡하고 관심사가 여러개일 클래스가 될 것입니다. API계층에서는 DTO클래스를, 서비스 계층에서는 엔티티 클래스를 사용해서 두 계층간 독립성을 보장하여야 합니다. 따라서 DTO클래스에 존재하는 데이터를 서비스 계층에서 사용하기 위해서, 엔티티 클래스에 존재하는 데이터를 API계층에서 사용하기 위해서는 DTO 객체와 엔티티 객체간 매핑이 필요로 합니다.



MapStruct

MapStruct 매퍼를 사용하기 위해서는 외부 라이브러리를 import해야 사용할 수 있습니다.

MapStruct는 매퍼(Mapper)구현 클래스를 자동으로 생성해주는 코드 자동 생성기입니다.

dependency{
	implementation 'org.mapstruct:mapstruct:1.4.2.Final'
    annotationProcessor 'org.mapstruct:mapStruct-processor:1.4.2.Final'
}

build.gradle에 추가해야 합니다.

MapStruct Mapper는 DTO 클래스와 엔티티 클래스를 바꿔줄 메서드를 정의하는 인터페이스 입니다.
즉 매개변수의 클래스타입을 리턴타입의 클래스로 변환해주는 메서드를 인터페이스로 정의하기만 하면 스프링에서 자동으로 구현체를 만들고 손쉽게 이용할 수있게 자동으로 만들어 줍니다.

@Mapper(componentModel = "spring")
public interface 매퍼{
	매핑된객체타입1 매퍼메서드1(매핑할객체타입1 매개변수);
    매핑된객체타입2 매퍼메서드2(매핑할객체타입2 매개변수);
    ...
}

@Mapper : Mapper 인터페이스임을 알리는 애너테이션 입니다.
componentModel = "spring" : 스프링 Bean으로 등록됩니다.
매핑할객체를 매개변수로 매핑된객체를 리턴타입으로 지정하면 Spring이 Mapper에서 매핑해주는 메서드를 구현한 클래스가 자동으로 만들어 줍니다.




후기

서비스 계층과 서비스계층에서 사용하기 위한 엔티티 클래스, DTO와의 매핑에대해 학습하였습니다. 어떤 비즈니스 로직을 설정하느냐에 따라 @Service클래스는 달라지겠지만, 이런방식으로 데이터를 계층내, 계층간으로 전달하는구나를 알 수 있었습니다.




GitHub

없음!

profile
오늘도 내일도 화이팅!

0개의 댓글