Spring Boot · 2026-02-12

Spring Boot에서 MapStruct로 DTO 매핑하기

Spring Boot에서 MapStruct를 이용한 DTO 매핑과 성능 최적화 방법을 예제 중심으로 정리. 설정, 매퍼 설계, 컬렉션 처리와 성능 개선 방법

작성일 : 2026-02-12 ㆍ 작성자 : 관리자
post
목차

서론

DTO 매핑은 계층 간 데이터 전달에서 반복적으로 등장한다. 매뉴얼로 필드를 복사하면 코드가 장황해지고 실수가 발생하기 쉽다. MapStruct는 컴파일 시점에 매핑 코드를 생성하는 도구로, 런타임 성능과 가독성 측면에서 유리하다. 이 글은 mapstruct spring boot 예제와 dto 매핑 mapstruct 적용법, mapstruct 성능 spring boot 관련 실무 팁을 중심으로 소개한다.

MapStruct 기본 개념

원리와 장점

MapStruct는 애노테이션을 통해 매핑 정의를 만들면, 어노테이션 프로세서가 컴파일 시점에 구현체를 생성한다. 따라서 리플렉션을 사용하지 않아 런타임 비용이 적다. 코드가 명시적이라 디버깅과 유지보수성이 좋다.

빌드 설정 (Maven 예제)

MapStruct를 사용하려면 애노테이션 프로세서가 빌드에 포함되어야 한다. 다음은 Maven 설정 예제이다.

<dependencies>
  <dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.5.5.Final</version>
  </dependency>
</dependencies>

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.8.1</version>
      <configuration>
        <annotationProcessorPaths>
          <path>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>1.5.5.Final</version>
          </path>
        </annotationProcessorPaths>
      </configuration>
    </plugin>
  </plugins>
</build>

기본 사용법

엔티티와 DTO 예제

public class User {
  private Long id;
  private String name;
  private String email;
  // getters, setters
}

public class UserDto {
  private Long id;
  private String name;
  // getters, setters
}

Mapper 인터페이스

Spring과 함께 사용하면 componentModel을 "spring"으로 설정해 빈 주입으로 재사용 가능하다.

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper(componentModel = "spring")
public interface UserMapper {
  UserDto userToUserDto(User user);
  User userDtoToUser(UserDto dto);
}

서비스에서 사용

import org.springframework.stereotype.Service;

@Service
public class UserService {
  private final UserMapper userMapper;
  private final UserRepository repo;

  public UserService(UserMapper userMapper, UserRepository repo) {
    this.userMapper = userMapper;
    this.repo = repo;
  }

  public UserDto getUser(Long id) {
    User user = repo.findById(id).orElseThrow();
    return userMapper.userToUserDto(user);
  }
}

실무 매핑 전략

중첩 객체와 컬렉션

중첩 객체는 별도의 매핑 메서드를 정의하면 MapStruct가 이를 자동으로 연결한다. 리스트 매핑은 요소 타입 매핑 메서드가 있으면 자동으로 적용된다.

선택적 필드와 무시 설정

불필요한 필드는 @Mapping(target = "field", ignore = true)로 무시한다. 불필요한 매핑을 줄이면 생성 코드가 간결해지고 런타임 작업도 줄어든다.

MapStruct 성능 최적화 팁

다음 항목은 mapstruct 성능 spring boot 환경에서 실제로 도움이 되는 권장 사항이다.

  • 컴포넌트 모델을 "spring"으로 설정해 싱글턴으로 재사용. 빈 주입으로 매퍼 구현을 재사용하면 불필요한 생성 비용을 회피할 수 있다.
  • 컬렉션 매핑은 요소 타입 매핑을 한 번만 정의한다. MapStruct가 내부에서 효율적으로 반복 처리하는 구현체를 생성한다.
  • 매핑 대상에서 사용하지 않는 필드는 명시적으로 ignore 처리해 불필요한 변환을 줄인다.
  • 엔티티의 지연 로딩 필드(Lazy)는 매핑 전에 필요한 필드만 초기화한다. 불필요한 DB 호출을 방지하면 전체 응답 성능 개선에 도움이 된다.
  • 병렬 스트림은 주의해서 사용. 매핑 구현이 상태 비저장이라도, 하위 로직(예: repository 호출)이 스레드 안전하지 않을 수 있다.
  • 성능 측정은 실제 워크로드로 진행. 마이크로벤치마크가 아닌 통합 테스트/프로파일링으로 병목을 찾는다.
  • MapStruct 버전 업데이트로 생성 코드 최적화가 포함될 수 있으므로 정기적 버전 검토 권장.

추가 팁: 컴파일 타임 확인 활용

MapStruct는 컴파일 시 미매핑 경고를 제공한다. 매핑 누락을 줄이면 런타임 예외 가능성이 낮아지고, 디버깅 비용도 줄어든다. unmappedTargetPolicy 설정을 통해 정책을 조정할 수 있다.

문제 상황과 해결책

빌드 시 구현체 생성이 안되는 경우

  • 애노테이션 프로세서가 설정되어 있는지 확인한다.
  • Maven/Gradle 캐시를 클린하고 재빌드한다.
  • IDE에서 어노테이션 프로세서 옵션이 활성화되어 있는지 점검한다.

매핑 결과가 null인 필드가 생길 때

소스 필드가 null인지, 매퍼 설정에서 ignore 처리했는지 확인한다. 필요한 경우 defaultExpression이나 nullValueMappingStrategy를 사용해 기본값을 설정할 수 있다.

결론

MapStruct는 dto 매핑 mapstruct 적용 시 생산성과 성능을 모두 개선하는 효과적인 도구다. mapstruct spring boot 예제처럼 componentModel을 활용하고 컬렉션 및 중첩 객체 매핑을 적절히 설계하면 실제 서비스에서 높은 효율을 기대할 수 있다. 또한 mapstruct 성능 spring boot 환경에서는 재사용 가능한 매퍼, 불필요한 필드 무시, 지연 로딩 주의 등 실무적인 최적화가 큰 차이를 만든다. 실전 적용 시에는 작은 케이스부터 측정하며 점진적으로 적용할 것을 권장한다.

mapstruct spring boot 예제 dto 매핑 mapstruct mapstruct 성능 spring boot spring boot mapstruct dto 매핑 mapstruct 설정 mapstruct 사용법 mapstruct 성능