wer erzÄhlt die nÄchsten 55+ minuten - inovex...wer erzÄhlt die nÄchsten 55+ minuten etwas?...

31

Upload: others

Post on 20-May-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)
Page 2: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTENETWAS?

Gerrit Brehmer, Karlsruhe

Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter) bei derinovex GmbH

In der Freizeit: Smart Home

Page 3: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

BEAN-MAPPING: EINSATZWann müssen Beans gemappt werden?

Entities zu DTOsinterne zu generierten Klassen (JAXB etc.)

zur Einbindung externer Dienstestandardisierten Schnittstelleneigenen REST/SOAP Schnittstellen

Allgemein Austauschformate zwischen Schichten und Applikationen

Page 4: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

BEAN MAPPING: UMSETZUNGWas benutzen wir dafür bisher?

von Hand geschriebener Mapping-Codetypsicher, schnellfehleranfällig, aufwendig

Dozerwenig Aufwand, Rekursives Auto-MappingReflection & XML: langsam

Apache Commons BeanUtilswenig AufwandReflection, nur nicht komplexe Properties, langsam

Page 5: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

GEHT ES BESSER?Wunschliste

schnelltypsicherwenig Aufwand

automatisches MappingNull-PrüfungenKonvertierungen von "ähnlichen" Typen

Fehlendes Mapping schnell erkennennachvollziehbar

Page 6: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

MAPSTRUCTmapstruct.org / github.com/mapstructOpenSource (Lizenz: Apache 2.0)Initator & Maintainer: Gunnar Morling (RedHat,Hibernate Team)Aktuelle Version: 1.0.0.CR2 (Final Release in Kürze)Weiterentwicklung/Support

mehrere Stamm-Entwicklerschnelles Feedbackkontinuierliche Weiterentwicklung

Page 7: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

WIE FUNKTIONIERT MAPSTRUCTAnnotation Processor

Verarbeitet Annotations am eigenen Quellcodesiehe andere bekannte Libs: JPA MetaModel, Lombok, QueryDSLz.B. mit Hilfe maven-processor-plugin

Generiert Java QuellcodeZusammenspiel verschiedener FreeMarker Templates

Page 8: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

DEMO

Page 9: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

INTEGRATION IN ECLIPSE #1MapStruct eclipse Plugin

noch work-in-progressHauptsächlich noch fehlende Features, keine Bugs

Code Completion: JAXB Listen, Nested PropertiesQuick Fix: Collection Mappings

Page 10: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

INTEGRATION IN ECLIPSE #2

m2e APT PluginAktivierung nichtvergessen!Inkompatibilitäten mitEclipse Compiler pre Mars(ab 1.0.0.CR2)Manchmal 'Clean Project'notwendig

Maven: build-helper-maven-plugin

automatische Build-PathAnpassung

Page 11: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

GENERIERTE ABHÄNGIGKEITENZu mappende Klassen sind ebenfalls generiert (z.B. JAXB per Schema)

Resultat: Compiler Fehler bei Generierung MapStruct MapperLösung:

Weiteres Maven Modul/Artefakt für abhängige KlassenMaven Plugins in unterschiedliche Phasen verlegen

Page 12: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

AUTOMAPPING #1Primitive & Wrapper-TypenDatums-Typen

Joda / Java 8 DateTime API KlassenDateCalendar

dest.setLocalDateTime(java.time.LocalDateTime.ofInstant( src.getDate().toInstant(), java.time.ZoneId.systemDefault()) );

Page 13: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

AUTOMAPPING #2Collection- & Array-Typen

Mapping nicht nur per SetterAdder (ohne Null Prüfung!)Getter (ohne Null Prüfung!)Setter

Mapping-Methoden zwischen Collection/Array Typen müssen nichtdefiniert werden

MapsJAXB

JAXBElementXMLGregorianCalendar

Page 14: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

VERSCHACHTELTE MAPPINGS@Mapping(source = "source.nested.param" target = "param") public Target toTarget(Source source);

inkl. Null-PrüfungenBisher nur für Quell-Parameter

Feature Request für Ziel-Parameter vorhanden

Page 15: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

MAPPING VON ENUM-TYPEN@Mapping(source = "FINAL", target = "LAST") TargetEnum map(SourceEnum enum);

String-Match oder explizites Mappingfehlende Mappings zu Zielwerten werden signalisiert

Page 16: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

MAPPING DEFAULTS UND KONSTANTEN@Mapping(source = "src", target = "dest", defaultValue = "-1")

Default-Werte als Ersatz bei null-Werten in Quell-Instanzen

@Mapping(constant = "CONST", target = "dest")

String-Konstanten, auf die bei Bedarf Standard-Converter oder andere Mapping Methodenangewendet werden

Page 17: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

QUALIFIERUnterscheidung bei identischem Quell- und Zieltyp

Ohne Qualifier Zuordnung nicht eindeutig = Compiler Fehlerspezielle Mappings für ansonsten automatisch generierten Mapping-Code

@Qualifier @Target(ElementType.METHOD)@Retention(RetentionPolicy.SOURCE) public @interface Marker { }

@Marker public String specialStringMapping(String source) { ... }

@Mapping(source = "src", target = "dest", qualifiedBy = Marker.class) public Target map(Source source);

Page 18: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

BEAN-FACTORIESAls Ersatz für Standard-KonstruktorSelbst geschriebene Factory-Methoden (leere Parameterliste,Rückgabetyp = Zieltyp)Generische Factories möglichVerwendung bereits vorhandener (z.B. ObjectFactory von JAXB)@Mapper(uses = CustomFactory.class) public interface Mapper { ... }

public class CustomFactory { public TargetDto createTargetDto() { .... } public <T extends AbstractEntity> T createEntity(@TargetType Class<T> entityClass) { ... } }

Page 19: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

MAPPING PER EXPRESSION@Mapping( expression = "java(java.util.UUID.randomUUID().toString())", target = "uniqueId") TargetDto mapTo(SourceEntity source);

Aktuell nur Unterstützung für Java Codeechte Skriptsprachen für zukünftige Versionen geplant

Notwendige Imports können am @Mapper konfiguriert werden

Page 20: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

UNTERSCHIEDLICHE QUELLEN@Mappings({ @Mapping(source = "param1.src", target = "dest1"), @Mapping(source = "param2.src", target = "dest2") }) Target map(SourceOne param1, SourceTwo param2);

Aber: Sind nur im Custom-Code / Expressions wiedervendbar

Page 21: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

MAPPING ALS UPDATE@Mapper public interface Mapper { Target update(Source src, @MappingTarget Target target); }

mehrere Quellen möglichReturn Type: void oder identisch mit Ziel-Typ

Page 22: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

BIDIREKTIONALES MAPPING@Mapper public interface Mapper {

@Mapping(source = "special", target = "destParam") Dto map(Entity source); @InheritInverseConfiguration Entity map(Dto source); }

Ausnahmengeschachtelte Quell-PropertyKonstantenExpressions

Page 23: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

CUSTOM MAPPER #1@Mapper(uses = CustomMapper.class) public interface Mapper { ... }

public class CustomMapper { public TargetDto toTarget(Source source) { .... } }

Mapper Klassennotwendig, wenn automatische Mapping-Methoden nichtgeneriert werden können

Einzelnes Element gemappt auf ListeListe mit Inhalten aus verschiedenen QuellenListe komplexer Elemente gemappt auf Liste primitiverWerte

Page 24: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

CUSTOM MAPPER #2@Mapper(uses = CustomMapper.class) public interface Mapper { ... }

@Mapper public abstract class CustomMapper { public TargetDto toTarget(Source source) { .... } @Mappings(...) public abstract NestingTargetDto toNestingTarget(NestingSource source); }

Abstrakte KlassenÄhnlich wie Mapper per Interface

abstrakte Methoden werden generiertpublic Methoden enthalten den nicht generierbaren Mapper-Code

Page 25: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

KOMPONENTENMODELLEKonfiguration pro MapperMehrere werden bereits unterstützt

Spring (@Component, @Autowired)CDI (@ApplicationScoped, @Inject)JSR 330 (@Named, @Inject)

Alle miteinander verbundenen Mapper müssen dasselbeKomponentenmodell verwendenKeine Abhängigkeit zu MapStruct zur Laufzeit

@Mapper(componentModel = "spring") public interface Mapper { ... }

@Component public class MapperImpl { ... }

Page 26: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

KONFIGURATION@MapperConfig(componentModel = ..., uses = ..., ...) public interface DefaultMapperConfig { ... }

@Mapper(config = "DefaultMapperConfig") public interface Mapper { ... }

Page 27: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

MAPPING ASPEKTE #1Decorator

angepasster Code für ausgewählte MethodenAber: greift nur, wenn Methode vom eigenen Code oder anderenMapper-Klassen aufgerufen wird

@Mapper @DecoratedWith(MapperDecorator.class) public interface Mapper { ... }

public abstract class MapperDecorator implements Mapper { private final Mapper delegate; public MapperDecorator(Mapper delegate) { this.delegate = delegate; } @Override public Target toTarget(Source source) { Target target = delegate.toTarget(source); // ... custom mapping ... }

Page 28: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

MAPPING ASPEKTE #2@BeforeMapping und @AfterMapping

Matching auf Mapping-Methoden anhand Quell- und Zieltypen@Mapper public abstract class Mapper { @BeforeMapping void flushEntity(AbstractEntity entity) { // flush entity to init all fields } @AfterMapping void manuelUpdateMissing(Source src, @MappingTarget Target target) { // e.g. as alternative for expressions / custom mapper } }

Page 29: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

EXCEPTIONHANDLINGChecked Exceptions

nur wenn an Mapping Methode deklariertansonsten gewrapped in RuntimeException

RuntimeExceptions ohne Anpassung

Page 30: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

FAZIT & AUSBLICKMapStruct ist ready-to-use

umfangreiche Dokumentationlebendige Communitykeine Bugs, die den Einsatz verhndern

Große Funktionsauswahl: Viele Wege führen zum Ziel!So viel wie möglich automatisch mappen

Damit verbundene Checks durch MapStruct minimieren MappingFehler

Das Feature-Set ist noch nicht komplett: Weitere nützliche Featureswerden sicher folgen!

Page 31: WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN - inovex...WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS? Gerrit Brehmer, Karlsruhe Auf der Arbeit: Software-Entwickler/Architekt ( / Projektleiter)

VIELEN DANK FÜR EURE AUFMERKSAMKEIT!