Задача отображения Entity <-> DTO типичная для layered architecture.
В Java для этого есть несколько библиотек:
https://mapstruct.org/https://github.com/DozerMapper/dozerhttp://modelmapper.org/У ModelMapper и Dozer используется единая точка преобразования объектов (
mapper.map(object, clazz)), однако эти библиотеки активно используют рефлексию, да и сама конфигурация мапперов не выглядит простой, особенно когда в проекте много классов для отображения.
MapStruct лишен этих недостатков, так как реализация маппинга генерируется во время компиляции по сигнатуре метода. Этот метод мы определяем в специальных абстрактных классах/интерфейсах - мапперах. Таких мапперов может быть очень много, если мы хотим разделить их по группам отображаемых классов. Конечно, можно объявить все методы преобразования в одном маппере, но тогда он окажется очень огромным и трудно поддерживаемым.
В Spring Framework идиоматичным способом отображения между двумя объектами являются интерфейсы:
org.springframework.core.convert.ConversionService
org.springframework.core.convert.converter.Converter
Мы можем сделать bean-definition нескольких кастомных конвертеров, зарегистрировать их в ConversionService, а потом использовать этот бин как единую точку преобразования объектов:
conversionService.convert(o, clazz)
.
В начале месяца команда MapStruct выпустила расширение для своей библиотеки - spring extensions. С помощью этого расширения любой ваш объявленный маппер будет зарегистрирован в ConversionService. Теперь будет не нужно инжектить кучу мапперов в нужный бин, раздувая его конструктор. Мы получили решение, которое по использованию очень напоминает Dozer/ModelMapper, но при этом не использует рефлексию и интегрировано в фреймворк.
https://mapstruct.org/news/2020-12-03-mapstruct-spring-extensions-0-0-1-released/https://mapstruct.org/news/2020-12-03-mapstruct-spring-extensions-0-0-1-released/https://mapstruct.org/news/2020-12-03-mapstruct-spring-extensions-0-0-1-released/Примеры можно посмотреть здесь:
https://github.com/mapstruct/mapstruct-spring-extensions/blob/master/examples/packagename-and-classname/src/main/java/org/mapstruct/extensions/spring/example/packageandclass/CarMapper.javahttps://github.com/mapstruct/mapstruct-spring-extensions/blob/master/examples/packagename-and-classname/src/test/java/org/mapstruct/extensions/spring/example/ConversionServiceAdapterIntegrationTest.java