欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring Boot 中集成 Lombok 和 MapStruct最佳實踐指南

 更新時間:2025年08月25日 11:52:53   作者:三石成山  
文章詳解SpringBoot項目中Lombok與MapStruct整合實踐,涵蓋版本兼容、IDE配置、代碼分層、映射配置、測試驗證及性能優(yōu)化,重點解決注解沖突、依賴注入等常見問題,強(qiáng)調(diào)分層管理和組件掃描配置,提升開發(fā)效率與代碼簡潔性,本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧

一、環(huán)境準(zhǔn)備

1. 版本兼容性要求

組件最低版本要求推薦版本
Spring Boot2.2.x+3.1.x
Lombok1.18.16+1.18.28
MapStruct1.4.2.Final+1.5.5.Final
JavaJDK 8+JDK 17

2. IDE 插件安裝

  • ??IntelliJ IDEA??:
    • 安裝 Lombok 插件 (Settings → Plugins)
    • 啟用注解處理 (Settings → Build → Compiler → Annotation Processors)

二、項目配置

1. Maven 配置

<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <!-- Lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.28</version>
        <scope>provided</scope>
    </dependency>
    <!-- MapStruct -->
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>1.5.5.Final</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>${java.version}</source>
                <target>${java.version}</target>
                <annotationProcessorPaths>
                    <!-- Lombok 處理器 -->
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                        <version>1.18.28</version>
                    </path>
                    <!-- MapStruct 處理器 -->
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>1.5.5.Final</version>
                    </path>
                    <!-- Lombok 與 MapStruct 的綁定器 -->
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok-mapstruct-binding</artifactId>
                        <version>0.2.0</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>

三、代碼實現(xiàn)

1. 實體類 (使用 Lombok)

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Long id;
    private String username;
    private String email;
    private LocalDateTime createTime;
}

2. DTO 類

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserDto {
    private Long id;
    private String name;
    private String emailAddress;
    private String createTimeFormatted;
}

3. Mapper 接口 (使用 MapStruct)

@Mapper(componentModel = "spring", imports = {DateTimeFormatter.class})
public interface UserMapper {
    @Mapping(source = "username", target = "name")
    @Mapping(source = "email", target = "emailAddress")
    @Mapping(target = "createTimeFormatted", 
             expression = "java(entity.getCreateTime().format(DateTimeFormatter.ISO_DATE_TIME))")
    UserDto toDto(User entity);
    @Mapping(source = "name", target = "username")
    @Mapping(source = "emailAddress", target = "email")
    User toEntity(UserDto dto);
    // 集合映射
    List<UserDto> toDtoList(List<User> entities);
    // 更新現(xiàn)有實例
    @Mapping(target = "id", ignore = true)
    void updateFromDto(UserDto dto, @MappingTarget User entity);
}

4. 服務(wù)層使用示例

@Service
@RequiredArgsConstructor
public class UserService {
    private final UserMapper userMapper;
    private final UserRepository userRepository;
    public UserDto getUserById(Long id) {
        return userMapper.toDto(
            userRepository.findById(id).orElseThrow()
        );
    }
    public List<UserDto> getAllUsers() {
        return userMapper.toDtoList(userRepository.findAll());
    }
    public UserDto createUser(UserDto userDto) {
        User user = userMapper.toEntity(userDto);
        return userMapper.toDto(userRepository.save(user));
    }
}

四、高級配置

1. 全局映射配置

@MapperConfig(
    componentModel = "spring",
    unmappedTargetPolicy = ReportingPolicy.IGNORE,
    nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE
)
public interface CentralConfig {}
// 在具體Mapper中引用
@Mapper(config = CentralConfig.class)
public interface ProductMapper {}

2. 自定義映射方法

@Mapper(componentModel = "spring")
public abstract class CustomMapper {
    // 自定義轉(zhuǎn)換邏輯
    protected String statusToString(Status status) {
        return status != null ? status.name() : "UNKNOWN";
    }
    // 抽象方法由MapStruct實現(xiàn)
    public abstract OrderDto toDto(Order entity);
}

3. 多源對象映射

@Mapper(componentModel = "spring")
public interface ComplexMapper {
    @Mapping(source = "user.username", target = "name")
    @Mapping(source = "profile.address", target = "location")
    @Mapping(source = "metadata.tags", target = "labels")
    CompositeDto mergeToDto(User user, UserProfile profile, Metadata metadata);
}

五、測試驗證

1. 單元測試示例

@SpringBootTest
public class UserMapperTest {
    @Autowired
    private UserMapper userMapper;
    @Test
    void testToDto() {
        User user = User.builder()
            .id(1L)
            .username("john_doe")
            .email("john@example.com")
            .createTime(LocalDateTime.now())
            .build();
        UserDto dto = userMapper.toDto(user);
        assertEquals(user.getUsername(), dto.getName());
        assertEquals(user.getEmail(), dto.getEmailAddress());
        assertNotNull(dto.getCreateTimeFormatted());
    }
    @Test
    void testToEntity() {
        UserDto dto = UserDto.builder()
            .name("jane_doe")
            .emailAddress("jane@example.com")
            .build();
        User user = userMapper.toEntity(dto);
        assertEquals(dto.getName(), user.getUsername());
        assertEquals(dto.getEmailAddress(), user.getEmail());
    }
}

2. 集成測試

@WebMvcTest(UserController.class)
@Import(UserMapper.class) // 顯式導(dǎo)入Mapper
public class UserControllerIT {
    @Autowired
    private MockMvc mockMvc;
    @MockBean
    private UserService userService;
    @Test
    void getUserById() throws Exception {
        UserDto mockDto = UserDto.builder().id(1L).name("test").build();
        when(userService.getUserById(any())).thenReturn(mockDto);
        mockMvc.perform(get("/api/users/1"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.name").value("test"));
    }
}

六、常見問題解決

1. Lombok 與 MapStruct 沖突

??現(xiàn)象??:編譯時報錯找不到 getter/setter
??解決??:

  1. 確保添加了 lombok-mapstruct-binding
  2. 檢查注解處理器順序 (Lombok 必須在 MapStruct 之前)

2. Spring 依賴注入失敗

??現(xiàn)象??:NoSuchBeanDefinitionException
??解決??:

  1. 確認(rèn) Mapper 接口有 @Mapper(componentModel = "spring")
  2. 檢查組件掃描范圍是否包含 Mapper 接口所在包

3. 集合映射問題

??現(xiàn)象??:集合映射為空
??解決??:

// 明確聲明集合映射方法
@Mapping(target = "items", source = "orderItems")
OrderDto toDto(Order entity);

4. 復(fù)雜類型轉(zhuǎn)換

??解決方案??:

@Mapper(componentModel = "spring")
public interface ComplexMapper {
    @Named("stringToDate")
    default LocalDate map(String dateStr) {
        return LocalDate.parse(dateStr, DateTimeFormatter.ISO_DATE);
    }
    @Mapping(target = "birthDate", source = "birthDateStr", qualifiedByName = "stringToDate")
    PersonDto toDto(Person entity);
}

七、性能優(yōu)化

1. 編譯參數(shù)優(yōu)化

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <compilerArgs>
            <arg>-Amapstruct.unmappedTargetPolicy=IGNORE</arg>
            <arg>-Amapstruct.defaultComponentModel=spring</arg>
            <arg>-Amapstruct.suppressGeneratorTimestamp=true</arg>
        </compilerArgs>
    </configuration>
</plugin>

2. 緩存映射器實例

@Mapper(componentModel = "spring")
public interface CachedMapper {
    @BeanMapping(resultType = CachedDto.class)
    CachedDto toCachedDto(Entity entity);
}

3. 批量映射優(yōu)化

public interface BatchMapper {
    @IterableMapping(elementTargetType = BatchDto.class)
    List<BatchDto> toBatchDtos(List<Entity> entities);
}

八、最佳實踐

  • ??分層管理 Mapper??:
    • 基礎(chǔ)映射放在 infrastructure/mapper 包
    • 業(yè)務(wù)特定映射放在對應(yīng)業(yè)務(wù)模塊中
  • ??文檔生成??:
@Mapper(componentModel = "spring")
public interface DocumentedMapper {
    /**
     * 用戶實體轉(zhuǎn)DTO
     * @param entity 用戶實體
     * @return 用戶DTO
     */
    @Mapping(source = "username", target = "name")
    UserDto toDto(User entity);
}

??版本控制??:

public interface UserMapperV2 extends UserMapper {
    // 擴(kuò)展或覆蓋方法
}

對重大變更創(chuàng)建 V2 版本映射器

通過以上配置和實踐,可以在 Spring Boot 項目中高效整合 Lombok 和 MapStruct,實現(xiàn)簡潔的代碼和高效的 DTO 轉(zhuǎn)換。

到此這篇關(guān)于Spring Boot 中集成 Lombok 和 MapStruct最佳實踐指南的文章就介紹到這了,更多相關(guān)Spring Boot 集成 Lombok 和 MapStruct內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java 實現(xiàn)圖片合成,并添加文字

    java 實現(xiàn)圖片合成,并添加文字

    這篇文章主要介紹了java 實現(xiàn)圖片合成,并添加文字的示例,幫助大家更好的利用Java處理圖片,感興趣的朋友可以了解下
    2020-12-12
  • 詳解SpringBoot中的統(tǒng)一功能處理的實現(xiàn)

    詳解SpringBoot中的統(tǒng)一功能處理的實現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了SpringBoot如何實現(xiàn)統(tǒng)一功能處理,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)或工作有一定借鑒價值,需要的可以參考一下
    2023-01-01
  • MyBatis動態(tài)Sql之if標(biāo)簽的用法詳解

    MyBatis動態(tài)Sql之if標(biāo)簽的用法詳解

    這篇文章主要介紹了MyBatis動態(tài)Sql之if標(biāo)簽的用法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值 ,需要的朋友可以參考下
    2019-07-07
  • 全面解釋Java中的serialVersionUID

    全面解釋Java中的serialVersionUID

    以下是對Java中的serialVersionUID進(jìn)行了全面的分析介紹。需要的朋友可以過來參考下
    2013-08-08
  • Java 遞歸遍歷實現(xiàn)linux tree命令方式

    Java 遞歸遍歷實現(xiàn)linux tree命令方式

    這篇文章主要介紹了Java 遞歸遍歷實現(xiàn)linux tree命令方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Spring Boot+Mybatis+Pagehelper分頁實現(xiàn)

    Spring Boot+Mybatis+Pagehelper分頁實現(xiàn)

    本篇文章主要講述的是Spring Boot+Mybatis+Pagehelper分頁實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Spring中的ApplicationRunner接口的使用詳解

    Spring中的ApplicationRunner接口的使用詳解

    這篇文章主要介紹了Spring中的ApplicationRunner接口的使用詳解,ApplicationRunner使用起來很簡單,只需要實現(xiàn)CommandLineRunner或者ApplicationRunner接口,重寫run方法就行,需要的朋友可以參考下
    2023-11-11
  • Java基于字符流形式讀寫數(shù)據(jù)的兩種實現(xiàn)方法示例

    Java基于字符流形式讀寫數(shù)據(jù)的兩種實現(xiàn)方法示例

    這篇文章主要介紹了Java基于字符流形式讀寫數(shù)據(jù)的兩種實現(xiàn)方法示,結(jié)合實例形式分析了java逐個字符讀寫及使用緩沖區(qū)進(jìn)行讀寫操作的具體實現(xiàn)技巧,需要的朋友可以參考下
    2018-01-01
  • 深度解析Spring AI請求與響應(yīng)機(jī)制的核心邏輯

    深度解析Spring AI請求與響應(yīng)機(jī)制的核心邏輯

    我們在前面的兩個章節(jié)中基本上對Spring Boot 3版本的新變化進(jìn)行了全面的回顧,以確保在接下來研究Spring AI時能夠避免任何潛在的問題,本文給大家介紹Spring AI請求與響應(yīng)機(jī)制的核心邏輯,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • Java項目如何打包成Jar的實現(xiàn)步驟

    Java項目如何打包成Jar的實現(xiàn)步驟

    一般情況下我們都是使用Java項目直接部署發(fā)布,有時需要我們將寫好的項目打成jar包,方便后期調(diào)用,本文主要介紹了Java項目如何打包成Jar,感興趣的可以了解一下
    2023-11-11

最新評論