Java annotation processor for the generation of type-safe bean mappers
npx @tessl/cli install tessl/maven-org-mapstruct--mapstruct@1.6.0MapStruct is a Java annotation processor that generates type-safe and performant mappers for Java bean classes at compile time. It eliminates the need for manual mapping code while providing excellent performance through plain method invocations and comprehensive type safety validation during compilation.
pom.xml:
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.6.3</version>
<scope>provided</scope>
</dependency>import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;For specific functionality:
import org.mapstruct.BeanMapping;
import org.mapstruct.IterableMapping;
import org.mapstruct.ValueMapping;
import org.mapstruct.BeforeMapping;
import org.mapstruct.AfterMapping;import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
// Define source and target classes
public class Car {
private String make;
private int numberOfSeats;
private CarType type;
// constructors, getters, setters...
}
public class CarDto {
private String make;
private int seatCount;
private String type;
// constructors, getters, setters...
}
// Create mapper interface
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
@Mapping(source = "numberOfSeats", target = "seatCount")
@Mapping(source = "type", target = "type")
CarDto carToCarDto(Car car);
@Mapping(source = "seatCount", target = "numberOfSeats")
Car carDtoToCar(CarDto carDto);
}
// Usage
Car car = new Car("Morris", 5, CarType.SEDAN);
CarDto carDto = CarMapper.INSTANCE.carToCarDto(car);MapStruct follows a compile-time code generation approach with several key components:
@Mapper interfaces during compilation and generates implementation classesThis design provides excellent performance, compile-time safety, and integration with modern Java development workflows while maintaining clean separation between mapping contracts and generated implementation code.
Primary annotations for defining mappers and configuring individual property mappings. These form the foundation of MapStruct's mapping capabilities.
@Target(ElementType.TYPE)
@interface Mapper {
String componentModel() default "default";
Class<?>[] uses() default {};
Class<?>[] imports() default {};
ReportingPolicy unmappedTargetPolicy() default ReportingPolicy.WARN;
ReportingPolicy unmappedSourcePolicy() default ReportingPolicy.IGNORE;
NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.RETURN_NULL;
}
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@interface Mapping {
String target();
String source() default "";
String constant() default "";
String expression() default "";
String defaultValue() default "";
boolean ignore() default false;
String dateFormat() default "";
String numberFormat() default "";
}Specialized mapping capabilities for collections, arrays, and map types with comprehensive configuration options for element transformation and null handling strategies.
@Target(ElementType.METHOD)
@interface IterableMapping {
String dateFormat() default "";
String numberFormat() default "";
Class<? extends Annotation>[] qualifiedBy() default {};
String[] qualifiedByName() default {};
Class<?> elementTargetType() default void.class;
NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.RETURN_NULL;
}
@Target(ElementType.METHOD)
@interface MapMapping {
String keyDateFormat() default "";
String valueDateFormat() default "";
String keyNumberFormat() default "";
String valueNumberFormat() default "";
Class<?> keyTargetType() default void.class;
Class<?> valueTargetType() default void.class;
}Advanced enum mapping capabilities supporting value transformations, name transformations, and comprehensive error handling for unmapped values.
@Target(ElementType.METHOD)
@interface ValueMapping {
String source();
String target();
}
@Target(ElementType.METHOD)
@interface EnumMapping {
String nameTransformationStrategy() default "";
String configuration() default "";
Class<? extends Exception> unexpectedValueMappingException() default IllegalArgumentException.class;
}Hooks and customization mechanisms for extending mapper behavior with custom logic, object factories, and lifecycle callbacks.
@Target(ElementType.METHOD)
@interface BeforeMapping {
}
@Target(ElementType.METHOD)
@interface AfterMapping {
}
@Target(ElementType.METHOD)
@interface ObjectFactory {
}
@Target(ElementType.TYPE)
@interface DecoratedWith {
Class<?> value();
}Configuration sharing, inheritance patterns, and qualifier systems for managing complex mapping scenarios and reusable mapping configurations.
@Target(ElementType.TYPE)
@interface MapperConfig {
String componentModel() default "default";
Class<?>[] uses() default {};
ReportingPolicy unmappedTargetPolicy() default ReportingPolicy.WARN;
NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.RETURN_NULL;
}
@Target(ElementType.METHOD)
@interface InheritConfiguration {
String name() default "";
}
@Target(ElementType.METHOD)
@interface InheritInverseConfiguration {
String name() default "";
}Advanced mapping control mechanisms, conditional mapping, subclass mapping, and fine-grained control over the mapping process.
@Target(ElementType.METHOD)
@interface Condition {
}
@Target(ElementType.METHOD)
@interface SubclassMapping {
Class<?> source();
Class<?> target();
Class<? extends Annotation>[] qualifiedBy() default {};
String[] qualifiedByName() default {};
}
@Target(ElementType.TYPE)
@interface MappingControl {
MappingControl[] value() default {};
}enum ReportingPolicy {
IGNORE, WARN, ERROR
}
enum NullValueMappingStrategy {
RETURN_NULL, RETURN_DEFAULT
}
enum NullValuePropertyMappingStrategy {
SET_TO_NULL, SET_TO_DEFAULT, IGNORE
}
enum NullValueCheckStrategy {
ON_IMPLICIT_CONVERSION, ALWAYS
}
enum CollectionMappingStrategy {
ACCESSOR_ONLY, SETTER_PREFERRED, ADDER_PREFERRED, TARGET_IMMUTABLE
}
enum InjectionStrategy {
FIELD, CONSTRUCTOR, SETTER
}
enum MappingInheritanceStrategy {
EXPLICIT, AUTO_INHERIT_FROM_CONFIG, AUTO_INHERIT_REVERSE_FROM_CONFIG, AUTO_INHERIT_ALL_FROM_CONFIG
}
enum SubclassExhaustiveStrategy {
COMPILE_ERROR, RUNTIME_EXCEPTION
}class Mappers {
public static <T> T getMapper(Class<T> clazz);
public static <T> Class<? extends T> getMapperClass(Class<T> clazz);
}
class MappingConstants {
public static final String NULL = "<NULL>";
public static final String ANY_REMAINING = "<ANY_REMAINING>";
public static final String ANY_UNMAPPED = "<ANY_UNMAPPED>";
public static final String THROW_EXCEPTION = "<THROW_EXCEPTION>";
class ComponentModel {
public static final String DEFAULT = "default";
public static final String CDI = "cdi";
public static final String SPRING = "spring";
public static final String JSR330 = "jsr330";
public static final String JAKARTA = "jakarta";
}
}