Mapowanie Dozer vs MapStruct

W aplikacjach wielowarstwowych często istnieje konieczność mapowania pomiędzy dwoma modelami danych. W tym artykule zostaną porównane dwie biblioteki ułatwiajace mapowanie w aplikacjach Java:

Najczęstszym przypadkiem użycia takich narzędzi jest kopiowanie danych z obiektów encji do obiektów DTO wykorzystywanych np. w usługach REST/SOAP.

 DozerMapStruct
Opis działaniaReguły mapowania są określane w plikach XML, które następnie są wczytywane w trakcie działania aplikacji.
Do obsługi mapowania wykorzystywany jest mechanizm refleksji.
Reguły mapowania określane są w plikach Java, głównie jako adnotacje. Na podstawie tych reguł przed kompilacją generowane są pliki Java klas, które są następnie wykorzystywane do mapowania.
SzybkośćDozer do mapowania obiektów wykorzystuje mechanizm refleksji, co powoduje, że jest on znacznie wolniejszy niż MapStruct.
W przykładowym projekcie (link) mapowane jest 1 000 000 obiektów.
Taka operacja zajmuje na moim komputerze ok. 16 sekund
MapStruct do mapowania wywołuje metody klas, które zostały wygenerowane przed kopilacją. Dzięki temu działa on znacznie szybciej niż Dozer.
W przykładowym projekcie (link) mapowane jest 1 000 000 obiektów.
Taka operacja zajmuje na moim komputerze ok. 3 sekund
MapStruct jest około 500% szybszy od Dozer’a.
Bezpieczeńtwo
Kiedy w pliku XML z regułami mapowania zostanie popełniona literówka, to informacja o błędzie  wyjdzie dopiero podczas wywołania mapowania w trakcie działania aplikacji.Kiedy zostanie popełniona literówka w nazwie mapowanych pól, informacja taka pojawi się już podczas kompilowania. Dzięki temu aplikacja będzie działała bardziej niezawodnie.
Obiekty immutableDozer może mieć dostęp do prywatnych pól (przez refleksję). To umożliwia mapowanie obiektów immutable, które nie posiadają setterów. Mapowanie jest możliwe, gdy obiekt immutable posiada konstruktor bezparametrowy i do plików mapujących zostanie dodany atrybut is-accessible="true" dla pól obiektu docelowego.Niestety MapStruct nie umożliwia mapowania obiektów immutable.
Jest otwarte zgłoszenie dotyczące tego tematu.
DebugowanieReguły mapowania określone są głównie w plikach XML. Następnie te pliki są wczytywane w trakcie działania aplikacji. Debugowanie procesu mapowania jest przez to bardzo utrudnione, breakpointy należy ustawiać w klasach biblioteki Dozer.Breakpoint można ustawić w klasach, które zostały wygenerowane podczas kompilacji. Dzięki temu można łatwo i szybko ustalić, które klasy są wykorzystywane podczas mapowania i przeanalizować ich działanie.
Popularność
(stan na dzień 23.03.2016)
Data utworzenia: 04.06.2005
Stackoverflow: 1610 postów
Github: https://github.com/DozerMapper/dozer
Data ostatniego wydania: 22.04.2014
Data utworzenia: 22.05.2012
Stackoverflow: 108 postów
Github: https://github.com/mapstruct/mapstruct
Data ostatniego wydania: 16.03.2016
Dodatkowe zalety
  1. Więcej domyślnych mapowań np. mapowanie typów Joda-Time, JAXBElement
  2. Kod mapowania tylko w plikach Java – szybsze ustalanie, który kod jest odpowiedzialny za dane mapowanie.
  3. Obsługa eventów (@BeforeMapping, @AfterMapping)
  4. Wbudowana obsługa dekoratorów

Przygotowałem małą aplikację, która wykonuje takie samo mapowanie za pomocą bibliotek Dozer oraz MapStruct. Można łatwo zauważyć różnicę w szybkości działania.

https://github.com/speedlog/mapping-tools-performance

Tłumaczenia: