Mastering MapStruct: Fast, Type‑Safe Java Bean Mapping with Real‑World Examples
This article introduces MapStruct, a compile‑time Java bean‑mapping code generator, explains its core concepts, shows step‑by‑step examples—including Maven dependencies, entity and DTO definitions, mapper interfaces, custom conversions, and advanced configurations—while comparing its performance to other copy utilities and highlighting deep‑copy behavior.
Official Introduction
MapStruct is a code generator that simplifies JavaBean mapping by generating plain‑method calls at compile time, offering fast, type‑safe, and easy‑to‑understand mapping implementations.
Why Use MapStruct
Multi‑layer applications often need to map between different object models (e.g., entities and DTOs). Writing such mapping code manually is tedious and error‑prone; MapStruct automates this process, providing high performance and thorough error checking.
How It Works
MapStruct is a Java annotation processor that can be used with Maven, Gradle, or IDEs. It uses sensible defaults but allows custom behavior through configuration.
Simple Implementation
1. Add Maven dependencies
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.3.0.Final</version>
</dependency>
// annotation processor
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.2.0.Final</version>
</dependency>2. Define entity and DTO classes
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Car {
private String make;
private int numberOfSeats;
private CarType type;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CarDto {
private String make;
private int seatCount;
private String type;
}3. Create mapper interface
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
@Mapping(source = "numberOfSeats", target = "seatCount")
CarDto carToCarDto(Car car);
}Analysis @Mapper marks the interface for MapStruct processing.
The mapping method converts a Car to CarDto; the method name is arbitrary. @Mapping handles properties with different names or types.
MapStruct generates an implementation class that can be obtained via Mappers.getMapper.
4. Generated implementation
The compiled target folder contains CarMapperImpl.class, which includes generated getters/setters and special handling for enums.
5. Client test
@Test
public void shouldMapCarToDto() {
Car car = new Car("Morris", 5, CarType.SEDAN);
CarDto carDto = CarMapper.INSTANCE.carToCarDto(car);
System.out.println(carDto);
}Mapper Configuration
The @Mapper annotation supports a componentModel attribute with four options:
default : obtain mapper via Mappers.getMapper.
cdi : generates an application‑scoped CDI bean, injectable with @Inject.
spring : generates a Spring bean, injectable with @Autowired.
jsr330 : generates a bean annotated with @Named and @Singleton, injectable with @Inject.
Custom implementations can also be injected using @Autowired.
Advanced Features
Using uses for custom conversions
@Mapper(uses = {BooleanStrFormat.class})
public interface CarMapper { ... }
@Component
public class BooleanStrFormat {
public String toStr(boolean type) { return type ? "Y" : "N"; }
public boolean toBoolean(String type) { return "Y".equals(type); }
}Mapping method example:
@Mapping(target = "type", expression = "java(new com.ittest.controller.BooleanStrFormat().toStr(carVo.isType()))")
CarDto carVoToDtoWithExpression(CarVo carVo);Multiple source objects to one target
Benz4SMall mallCarToBenzMall(Car car, Mall4S mall4S);Generated implementation merges fields from both sources.
Updating existing objects
void updateBwmCar(Car car, @MappingTarget BMWCar bwmCar);MapStruct generates code that copies non‑null source fields into the target instance.
Deep vs. Shallow Copy
MapStruct creates new objects, performing a deep copy rather than a shallow reference copy.
Performance Comparison
Benchmarks show MapStruct outperforms manual copy, cglib, Spring BeanUtils, Apache BeanUtils, and others, achieving roughly 10× the speed of Apache BeanUtils and 4‑5× that of Spring BeanUtils for large data volumes.
Conclusion: For high‑performance bean mapping, especially with large datasets, MapStruct (or BeanCopier) provides the best speed and type safety.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Su San Talks Tech
Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
