Skip to content

Commit 04c6bcd

Browse files
authored
Merge pull request #16 from mapstruct/issue4-user-documentation
Issue4 user documentation
2 parents 51de316 + a258db2 commit 04c6bcd

File tree

6 files changed

+319
-0
lines changed

6 files changed

+319
-0
lines changed

docs/build.gradle

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
plugins {
2+
id 'org.asciidoctor.jvm.convert' version '3.2.0'
3+
}
4+
5+
asciidoctor {
6+
baseDirFollowsSourceDir()
7+
attributes 'source-highlighter': 'coderay',
8+
'icons': 'font',
9+
'mapstructSpringExtensionsVersion': "${project.version}"
10+
11+
sources {
12+
include 'mapstruct-spring-extensions-reference-guide.asciidoc'
13+
}
14+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[[introduction]]
2+
== Introduction
3+
4+
The MapStruct Spring Extensions are a Java http://docs.oracle.com/javase/6/docs/technotes/guides/apt/index.html[annotation processor] extending the well known https://mapstruct.org/[MapStruct project] with features specific to the https://spring.io/[Spring Framework].
5+
6+
All you have to do is to define your MapStruct mapper to extend Spring's https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#core-convert-Converter-API[Converter interface]. During compilation, the extensions will generate an adapter which allows the standard MapStruct mappers to use Spring's https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#core-convert-ConversionService-API[ConversionService].
7+
8+
This enables the developer to define MapStruct mappers with only the `ConversionService` in their `uses` attribute rather than having to import every single Mapper individually, thus allowing for looser coupling between Mappers.
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
[[setup]]
2+
== Set up
3+
4+
MapStruct Spring Extensions is a Java annotation processor based on http://www.jcp.org/en/jsr/detail?id=269[JSR 269] and as such can be used within command line builds (javac, Ant, Maven etc.) as well as from within your IDE. Also, you will need MapStruct itself (at least version `1.4.0.Final`) in your project.
5+
6+
It comprises the following artifacts:
7+
8+
* _org.mapstruct.extensions.spring:mapstruct-spring-annotations_: contains the added annotations such as `@SpringMapperConfig`
9+
* _org.mapstruct.extensions.spring:mapstruct-spring-extensions_: contains the annotation processor which generates Spring components
10+
11+
=== Apache Maven
12+
13+
For Maven based projects add the following to your POM file in order to use MapStruct Spring Extensions:
14+
15+
.Maven configuration
16+
====
17+
[source, xml, linenums]
18+
[subs="verbatim,attributes"]
19+
----
20+
...
21+
<properties>
22+
<org.mapstruct.extensions.spring.version>{mapstructSpringExtensionsVersion}</org.mapstruct.extensions.spring.version>
23+
</properties>
24+
...
25+
<dependencies>
26+
<dependency>
27+
<groupId>org.mapstruct.extensions.spring</groupId>
28+
<artifactId>mapstruct-spring-annotations</artifactId>
29+
<version>${org.mapstruct.extensions.spring.version}</version>
30+
</dependency>
31+
</dependencies>
32+
...
33+
<build>
34+
<plugins>
35+
<plugin>
36+
<groupId>org.apache.maven.plugins</groupId>
37+
<artifactId>maven-compiler-plugin</artifactId>
38+
<version>3.8.1</version>
39+
<configuration>
40+
<source>1.8</source>
41+
<target>1.8</target>
42+
<annotationProcessorPaths>
43+
<path>
44+
<groupId>org.mapstruct.extensions.spring</groupId>
45+
<artifactId>mapstruct-spring-extensions</artifactId>
46+
<version>${org.mapstruct.extensions.spring.version}</version>
47+
</path>
48+
</annotationProcessorPaths>
49+
</configuration>
50+
</plugin>
51+
</plugins>
52+
</build>
53+
...
54+
----
55+
====
56+
57+
[TIP]
58+
====
59+
If you are working with the Eclipse IDE, make sure to have a current version of the http://www.eclipse.org/m2e/[M2E plug-in].
60+
When importing a Maven project configured as shown above, it will set up the MapStruct Spring Extensions annotation processor so it runs right in the IDE, whenever you save a mapper type extending a Spring converter.
61+
Neat, isn't it?
62+
63+
To double check that everything is working as expected, go to your project's properties and select "Java Compiler" -> "Annotation Processing" -> "Factory Path".
64+
The MapStruct Spring Extensions JAR should be listed and enabled there.
65+
Any processor options configured via the compiler plug-in (see below) should be listed under "Java Compiler" -> "Annotation Processing".
66+
67+
If the processor is not kicking in, check that the configuration of annotation processors through M2E is enabled.
68+
To do so, go to "Preferences" -> "Maven" -> "Annotation Processing" and select "Automatically configure JDT APT".
69+
Alternatively, specify the following in the `properties` section of your POM file: `<m2e.apt.activation>jdt_apt</m2e.apt.activation>`.
70+
71+
Also make sure that your project is using Java 1.8 or later (project properties -> "Java Compiler" -> "Compile Compliance Level").
72+
It will not work with older versions.
73+
====
74+
75+
=== Gradle
76+
77+
Add the following to your Gradle build file in order to enable MapStruct Spring Extensions:
78+
79+
.Gradle configuration (5.2 and later)
80+
====
81+
[source, groovy, linenums]
82+
[subs="verbatim,attributes"]
83+
----
84+
...
85+
86+
dependencies {
87+
...
88+
implementation "org.mapstruct.extensions.spring:mapstruct-spring-annotations:${mapstructSpringExtensionsVersion}"
89+
annotationProcessor "org.mapstruct.extensions.spring:mapstruct-spring-extensions:${mapstructSpringExtensionsVersion}"
90+
91+
// If you are using MapStruct Spring Extensions in test code
92+
testAnnotationProcessor "org.mapstruct.extensions.spring:mapstruct-spring-extensions:${mapstructSpringExtensionsVersion}"
93+
}
94+
...
95+
----
96+
====
97+
.Gradle configuration (3.4 - 5.1)
98+
====
99+
[source, groovy, linenums]
100+
[subs="verbatim,attributes"]
101+
----
102+
...
103+
plugins {
104+
...
105+
id 'net.ltgt.apt' version '0.20'
106+
}
107+
108+
// You can integrate with your IDEs.
109+
// See more details: https://github.com/tbroyer/gradle-apt-plugin#usage-with-ides
110+
apply plugin: 'net.ltgt.apt-idea'
111+
apply plugin: 'net.ltgt.apt-eclipse'
112+
113+
dependencies {
114+
...
115+
implementation "org.mapstruct.extensions.spring:mapstruct-spring-annotations:${mapstructSpringExtensionsVersion}"
116+
annotationProcessor "org.mapstruct.extensions.spring:mapstruct-spring-extensions:${mapstructSpringExtensionsVersion}"
117+
118+
// If you are using MapStruct Spring Extensions in test code
119+
testAnnotationProcessor "org.mapstruct.extensions.spring:mapstruct-spring-extensions:${mapstructSpringExtensionsVersion}"
120+
}
121+
...
122+
----
123+
====
124+
.Gradle (3.3 and older)
125+
====
126+
[source, groovy, linenums]
127+
[subs="verbatim,attributes"]
128+
----
129+
...
130+
plugins {
131+
...
132+
id 'net.ltgt.apt' version '0.20'
133+
}
134+
135+
// You can integrate with your IDEs.
136+
// See more details: https://github.com/tbroyer/gradle-apt-plugin#usage-with-ides
137+
apply plugin: 'net.ltgt.apt-idea'
138+
apply plugin: 'net.ltgt.apt-eclipse'
139+
140+
dependencies {
141+
...
142+
compile "org.mapstruct.extensions.spring:mapstruct-spring-annotations:${mapstructSpringExtensionsVersion}"
143+
annotationProcessor "org.mapstruct.extensions.spring:mapstruct-spring-extensions:${mapstructSpringExtensionsVersion}"
144+
145+
// If you are using MapStruct Spring Extensions in test code
146+
testAnnotationProcessor "org.mapstruct.extensions.spring:mapstruct-spring-extensions:${mapstructSpringExtensionsVersion}"
147+
}
148+
...
149+
----
150+
====
151+
152+
153+
=== Apache Ant
154+
155+
Add the `javac` task configured as follows to your _build.xml_ file in order to enable MapStruct Spring Extensions in your Ant-based project. Adjust the paths as required for your project layout.
156+
157+
.Ant configuration
158+
====
159+
[source, xml, linenums]
160+
[subs="verbatim,attributes"]
161+
----
162+
...
163+
<javac
164+
srcdir="src/main/java"
165+
destdir="target/classes"
166+
classpath="path/to/mapstruct-spring-annotations{mapstructSpringExtensionsVersion}.jar">
167+
<compilerarg line="-processorpath path/to/mapstruct-spring-extensions-{mapstructSpringExtensionsVersion}.jar"/>
168+
<compilerarg line="-s target/generated-sources"/>
169+
</javac>
170+
...
171+
----
172+
====
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
[[mapperAsConverter]]
2+
== Mappers as Converters
3+
4+
MapStruct Mappers nicely match Spring's https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#core-convert-Converter-API[Converter] idea:
5+
====
6+
[source, java, linenums]
7+
[subs="verbatim,attributes"]
8+
----
9+
@Mapper
10+
public interface CarMapper extends Converter<Car, CarDto> {
11+
@Mapping(target = "seats", source = "seatConfiguration")
12+
CarDto convert(Car car);
13+
}
14+
----
15+
====
16+
17+
This allows using the Mapper indirectly via the `ConversionService`:
18+
19+
====
20+
[source, java, linenums]
21+
[subs="verbatim,attributes"]
22+
----
23+
...
24+
@Autowired
25+
private ConversionService conversionService;
26+
...
27+
Car car = ...;
28+
CarDto carDto = conversionService.convert(car, CarDto.class);
29+
----
30+
====
31+
32+
All this can be achieved already with MapStruct's core functionality. However, when a Mapper wants to https://mapstruct.org/documentation/stable/reference/html/#invoking-other-mappers[invoke] another one, it can't take the route via the `ConversionService`, because the latter's `convert` method does not match the signature that MapStruct expects for a mapping method. Thus, the developer still has to add every invoked Mapper to the invoking Mapper's `uses` element. This creates (aside from a potentially long list) a tight coupling between Mappers that the `ConversionService` wants to avoid.
33+
34+
This is where MapStruct Spring Extensions can help. Including the two artifacts in your build will generate an Adapter class that _can_ be used by an invoking Mapper. Let's say that the above CarMapper is accompanied by a SeatConfigurationMapper:
35+
====
36+
[source, java, linenums]
37+
[subs="verbatim,attributes"]
38+
----
39+
@Mapper
40+
public interface SeatConfigurationMapper extends Converter<SeatConfiguration, SeatConfigurationDto> {
41+
@Mapping(target = "seatCount", source = "numberOfSeats")
42+
@Mapping(target = "material", source = "seatMaterial")
43+
SeatConfigurationDto convert(SeatConfiguration seatConfiguration);
44+
}
45+
----
46+
====
47+
48+
The generated Adapter class will look like this:
49+
50+
====
51+
[source, java, linenums]
52+
[subs="verbatim,attributes"]
53+
----
54+
@Component
55+
public class ConversionServiceAdapter {
56+
@Autowired
57+
private ConversionService conversionService;
58+
59+
public CarDto mapCarToCarDto(final Car source) {
60+
return conversionService.convert(source, CarDto.class);
61+
}
62+
63+
public SeatConfigurationDto mapSeatConfigurationToSeatConfigurationDto(final SeatConfiguration source) {
64+
return conversionService.convert(source, SeatConfigurationDto.class);
65+
}
66+
}
67+
----
68+
====
69+
70+
Since this class' methods match the signature that MapStruct expects, we can now add it to the CarMapper:
71+
====
72+
[source, java, linenums]
73+
[subs="verbatim,attributes"]
74+
----
75+
@Mapper(uses = ConversionServiceAdapter.class)
76+
public interface CarMapper extends Converter<Car, CarDto> {
77+
@Mapping(target = "seats", source = "seatConfiguration")
78+
CarDto convert(Car car);
79+
}
80+
----
81+
====
82+
83+
[[mappersAsConvertersCustomNames]]
84+
=== Custom Names
85+
By default, the generated class will be located in the package `org.mapstruct.extensions.spring.converter` and receive the name `ConversionServiceAdapter`. Typically, you will want to change these names, most often at least the package. This can be accomplished by adding the `SpringMapperConfig` annotation on any class within your regular source code. One natural candidate would be your https://mapstruct.org/documentation/stable/reference/html/#shared-configurations[shared configuration] if you use this:
86+
====
87+
[source, java, linenums]
88+
[subs="verbatim,attributes"]
89+
----
90+
import org.mapstruct.MapperConfig;
91+
import org.mapstruct.extensions.spring.SpringMapperConfig;
92+
import org.mapstruct.extensions.spring.example.adapter.MyAdapter;
93+
94+
@MapperConfig(componentModel = "spring", uses = MyAdapter.class)
95+
@SpringMapperConfig(conversionServiceAdapterPackage ="org.mapstruct.extensions.spring.example.adapter", conversionServiceAdapterClassName ="MyAdapter")
96+
public interface MapperSpringConfig {
97+
}
98+
----
99+
====
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
= MapStruct {mapstructSpringExtensionsVersion} Reference Guide
2+
:revdate: {docdate}
3+
:toc: right
4+
:sectanchors:
5+
:Author: Raimund Klein
6+
7+
[[Preface]]
8+
== Preface
9+
This is the reference documentation of the MapStruct Spring Extensions, an annotation processor designed to complement the core MapStruct project with features specific to the Spring Framework.
10+
This guide covers all the functionality provided by the MapStruct Spring Extensions. In case this guide doesn't answer all your questions just join the MapStruct https://groups.google.com/forum/?fromgroups#!forum/mapstruct-users[Google group] to get help.
11+
12+
Please note that this guide assumes some familiarity with the MapStruct core. If this is your first introduction to MapStruct, you might wish to start with the https://mapstruct.org/documentation/stable/reference/html/[core documentation].
13+
14+
You found a typo or other error in this guide? Please let us know by opening an issue in the https://github.com/mapstruct/mapstruct-spring-extensions[MapStruct Spring Extensions GitHub repository],
15+
or, better yet, help the community and send a pull request for fixing it!
16+
17+
This work is licensed under the http://creativecommons.org/licenses/by-sa/4.0/[Creative Commons Attribution-ShareAlike 4.0 International License].
18+
19+
:numbered:
20+
21+
include::chapter-1-introduction.asciidoc[]
22+
23+
include::chapter-2-set-up.asciidoc[]
24+
25+
include::chapter-3-mapper-as-converter.asciidoc[]

settings.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ include "examples:noconfig"
88
include "examples:packagename"
99
include "examples:classname"
1010
include "examples:packagename-and-classname"
11+
include "docs"

0 commit comments

Comments
 (0)