MapStruct in Spring Boot Applications


Injecting Mappers as Spring Beans

MapStruct integrates smoothly with Spring by allowing mappers to be registered as Spring beans. To enable this, you simply annotate your mapper interface with @Mapper(componentModel = "spring"). This allows you to inject the mapper into your services using @Autowired or constructor injection.


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

@Service
public class UserService {
    private final UserMapper userMapper;

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

Best Practices for Layered Architectures

In a layered Spring Boot architecture, MapStruct mappers are best placed between the service and DTO layers. This separation keeps domain models clean and maintains a clear boundary between internal logic and external representations.

Recommended practice:

  • Use DTOs in controller and REST layers.
  • Map DTOs to domain models in the service layer.
  • Keep mapping logic centralized in dedicated mapper interfaces.

Performance Comparison with Reflection-Based Mappers

One of the major advantages of MapStruct is its compile-time code generation. Unlike reflection-based mappers (e.g., ModelMapper or Dozer), MapStruct generates type-safe mapping code during build time, eliminating the runtime cost of introspection.

Benefits of MapStruct over reflection-based mappers:

  • Better performance due to zero reflection overhead.
  • Compile-time validation of mappings (errors caught early).
  • Improved readability and debuggability of mapping logic.

Integration with Lombok

MapStruct and Lombok can be used together effectively. To ensure compatibility, especially with generated getters/setters and constructors, make sure to enable the correct annotation processor setup in your build tool (e.g., Gradle or Maven).

You can also use @Builder with MapStruct by enabling builder support:


@Mapper(componentModel = "spring", builder = @Builder(disableBuilder = false))
public interface ProductMapper {
    ProductDto toDto(Product product);
}

Make sure annotation processing is enabled in your IDE and build configuration. Using mapstruct-lombok extensions can help further bridge compatibility gaps when working with immutable objects.

Conclusion

MapStruct offers a powerful, fast, and type-safe alternative to reflection-based mappers in Spring Boot applications. When integrated correctly, it aligns perfectly with layered architecture principles and works well alongside tools like Lombok, making it a top choice for modern enterprise applications.

Post a Comment

0 Comments