Почему не используется MapStruct для маппинга объектов
Что проверяют
Понимаете ли вы, как устроен MapStruct, и умеете ли обосновывать отказ от библиотеки не вкусом, а ограничениями проекта. Вопрос обычно звучит про конкретный код: маппинг написан руками, и интервьюер хочет услышать решение, а не оправдание.
Как отвечать
Сначала показать, что вы знаете предмет. MapStruct это генератор кода на этапе компиляции: обработчик аннотаций разворачивает интерфейс маппера в обычный класс с вызовами геттеров и сеттеров. Рефлексии в рантайме нет, несовпадение полей видно на сборке, а не в проде. Поэтому аргумент «медленно» к нему не относится.
Дальше назвать реальные причины отказа:
- маппинг несёт логику: условия, обращение к справочнику, сборка результата из двух источников. В генераторе это превращается в россыпь методов
@Namedи вставокexpression = "java(...)", читать такое хуже обычного метода; - пар DTO две или три, и заводить ради них ещё один обработчик аннотаций дороже, чем написать руками;
- сборка: Lombok и MapStruct обязаны идти в нужном порядке в
annotationProcessorPathsвместе с lombok-mapstruct-binding, иначе маппер собирается пустым; - в проекте уже принят один подход, и смешивать два хуже, чем держать любой один.
Хорошо закончить симметрично: MapStruct выигрывает там, где много плоских DTO, особенно со строгим режимом unmappedTargetPolicy = ReportingPolicy.ERROR, который ловит забытое поле ещё на сборке.
Где спотыкаются
Называют причиной производительность и рефлексию. Это претензия к ModelMapper и Dozer, которые сопоставляют поля в рантайме. MapStruct генерирует прямые присваивания и по скорости равен ручному коду.
Говорят про сложную логику без единого примера. Такой ответ звучит отговоркой, а конкретный случай (два источника, разные версии внешнего API, вычисляемое поле) звучит как опыт.
Жалуются, что маппер «не заработал», и не разбираются почему. Обычно это молча незаполненные поля из-за политики по умолчанию или порядок обработчиков с Lombok. Признать ошибку в настройке честнее, чем обвинять библиотеку.