MapStruct
は、1.4.0.Final
よりコンストラクタの呼び出しによるマッピングを正式にサポートしています。
この機能により、Kotlin
のdata class
へのマッピングもできるようになったため、実際にやってみます。
この記事では、MapStruct 1.4.1.Final
を利用します。
- mapstruct/mapstruct: An annotation processor for generating type-safe bean mappers
- MapStruct 1.4.1.Final bug fix released – MapStruct
コード例
src/dst
例として、以下のsrc
とdst
を行います。
data class Src(
var arg0: Int,
var arg1: Int,
var arg2: Int,
var arg3: Int,
var arg4: Int
)
data class Dst(
var arg0: Int,
var arg1: Int,
var arg2: Int,
var arg3: Int,
var arg4: Int
)
マッパー
マッパーの定義は以下の通りです。
injectionStrategy = InjectionStrategy.CONSTRUCTOR
を指定することで、コンストラクタ呼び出しができます。
import org.mapstruct.InjectionStrategy;
import org.mapstruct.Mapper;
@Mapper(injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public interface MapStructConstructorMapper {
Dst map(Src src);
}
生成されたコード
生成されたコードは以下の通りです。
確かにコンストラクタが呼び出されています。
import javax.annotation.Generated;
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2021-01-31T00:44:38+0900",
comments = "version: 1.4.1.Final, compiler: IncrementalProcessingEnvironment from gradle-language-java-6.1.1.jar, environment: Java 1.8.0_241 (Oracle Corporation)"
)
public class MapStructConstructorMapperImpl implements MapStructConstructorMapper {
@Override
public Dst map(Src src) {
if ( src == null ) {
return null;
}
int arg0 = 0;
int arg1 = 0;
int arg2 = 0;
int arg3 = 0;
int arg4 = 0;
arg0 = src.getArg0();
arg1 = src.getArg1();
arg2 = src.getArg2();
arg3 = src.getArg3();
arg4 = src.getArg4();
Dst dst = new Dst( arg0, arg1, arg2, arg3, arg4 );
return dst;
}
}
呼び出し
以下のようにすることで、Kotlin
のdata class
へマッピングできます。
val src = Src(1, 2, 3, 4, 5)
val mapStructConstructor: MapStructConstructorMapper = Mappers.getMapper(MapStructConstructorMapper::class.java)
val dst = mapStructConstructor.map(src)
println(dst) // -> Dst(arg0=1, arg1=2, arg2=3, arg3=4, arg4=5)
補足
試した所、Kotlin no-arg plugin
などで無引数コンストラクタを生成している場合、injectionStrategy = InjectionStrategy.CONSTRUCTOR
を指定してもコンストラクタを呼び出すコードが生成されませんでした。
また、interface
をKotlin
で書いた場合コード生成が機能しないようでした。
これに関しては、調べた所gradle
の設定で回避できるかもしれませんでしたが、簡単のため一旦Java
で書いています。