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.