簡體   English   中英

MapStruct 實現在 Spring Boot Web 應用程序中不起作用

[英]MapStruct implementation is not working in Spring Boot Web Application

我是 Spring Boot 和MapStruct工具的新手。

早些時候,一個項目(由其他團隊使用這些技術編寫)沒有啟動。 然后,我在 Mapper 抽象類中做了一些更改,但現在映射器對象在應用程序啟動時變為 null。

映射器抽象類:

@Mapper(componentModel = "spring")
public abstract class UserAndEmployeeMapper {

    public UserAndEmployeeMapper INSTANCE = Mappers.getMapper( UserAndEmployeeMapper.class );

    @Mapping(source = "username", target = "name")
    @Mapping(source = "ssn", target = "ssn", defaultValue = "xxxxxx" )
    @Mapping(target = "salary", constant = "34.67")
    @Mapping(target = "dob", dateFormat = "dd/MM/yyyy", constant = "10/12/2002")
    public abstract Employee mapToEmployee(User user);

    public abstract List<Employee> mapToEmployee(List<User> users);

    @Mapping(source = "name", target = "username")
    public abstract User mapToUser(Employee employee);

    public abstract List<User> mapToUser(List<Employee> employees);

}

LoginServiceImpl 類

@Service("loginService")
public class LoginServiceImpl implements LoginService{

    private static final AtomicLong counter = new AtomicLong();

    @Autowired
    private EmployeeDao employeeDao;

    private UserAndEmployeeMapper userAndEmployeeMapper;
...

}

pom.xml

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${mapstruct.jdk8.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
</build>

在 LoginServiceImpl 中添加 @Autowired 后,應用程序未啟動並顯示以下錯誤日志

***************************
APPLICATION FAILED TO START
***************************

Description:

Field userAndEmployeeMapper in org.service.impl.LoginServiceImpl required a bean of type 'org.mapper.UserAndEmployeeMapper' that could not be found.


Action:

Consider defining a bean of type 'org.mapper.UserAndEmployeeMapper' in your configuration.

有什么建議么 ?

首先, public UserAndEmployeeMapper INSTANCE = Mappers.getMapper( UserAndEmployeeMapper.class ); 只能與默認組件模型一起使用,否則可能會導致UserAndEmployeeMapper未正確初始化。

LoginServiceImpl中的UserAndEmployeeMapper必須使用@Autowired注解,否則 Spring 無法將其注入,這就是它為null的原因。

我不知道你的包結構。 如果您的 Spring Boot 應用程序類在包org中,那么它將獲取UserAndEmployeeMapperImpl 否則,請確保 spring 配置選擇UserAndEmployeeMapperImpl

如果上面的所有內容都正確設置並且您正在通過 IDE 啟動應用程序,請確保target/generated-sources或 Gradle 的替代項是您的源的一部分並被拾取。 查看IDE 支持以確保您已正確設置 IDE 的注釋處理器發現。 例如,IntelliJ 不會使用您當前的設置調用 MapStruct 注釋處理器,它不會從 maven 編譯器中獲取annotationProcessorPaths

將抽象類作為接口對我有用。

public interface UserAndEmployeeMapper {

我也遇到了這個問題,將mapper從抽象類更改為接口對我來說不起作用。

我結束了:

  • 從映射器接口中刪除INSTANCE屬性
  • 創建一個實現接口的類,實現mappes方法
  • 在需要映射器的類中添加此類的實例作為@Autowired屬性,並調用它。

WebAppMapper.java

    @Mapper(componentModel = "spring")
    public interface WebAppMapper {
        CatalogData createCatalogRequestToData(CreateCatalogRequest createCatalogRequest);
    }

WebAppMapperImpl.java

@Component
public class WebAppMapperImpl implements WebAppMapper {
    @Override
    public CatalogData createCatalogRequestToData(CreateCatalogRequest createCatalogRequest) {
        CatalogData catalogData = new CatalogData();
        catalogData.setId(createCatalogRequest.getId());
        catalogData.setName(createCatalogRequest.getName());
        return catalogData;
    }
}

CatalogController.java

@Autowired
WebAppMapper webAppMapper;

webAppMapper.createCatalogRequestToData(createCatalogRequest);

這對我有用。

springfox-swagger2 依賴項在排除它並在 pom.xml 中添加特定版本的 mapstruct 依賴項后加載舊版本的 mapstruct 它開始生成源

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.2.2</version>
<exclusions>
 <exclusion>
 <groupId>org.mapstruct</groupId>
  <artifactId>mapstruct</artifactId>
 </exclusion>
</exclusions>

在地圖結構依賴項下方添加

<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.3.0.Beta1</version>

為了使所有映射器類都符合 Spring bean 的要求,請將以下 compilerArgs 添加到您的 maven-compiler-plugin。

<compilerArgs>
<arg>-Amapstruct.suppressGeneratorTimestamp=true</arg>
<arg>-Amapstruct.defaultComponentModel=spring</arg>
</compilerArgs> 

如果使用 maven-processor-plugin 添加以下選項

<options>                       
<mapstruct.suppressGeneratorTimestamp>
true
</mapstruct.suppressGeneratorTimestamp>                      
<mapstruct.defaultComponentModel>
spring
</mapstruct.defaultComponentModel>
</options>

在 pom.xml 中試試這個:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>17</source>
                <target>17</target>
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>1.4.2.Final</version>
                    </path>
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                        <version>1.18.22</version>
                    </path>
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok-mapstruct-binding</artifactId>
                        <version>0.2.0</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>

並重新加載 Maven (ALT+F5)

就我而言,我認為錯誤是由於 build.gradle 不完整造成的。

dependencies {
    compile group: 'org.mapstruct', name: 'mapstruct-processor', version: '1.2.0.Final'
}

apply plugin: 'net.ltgt.apt'

dependencies {
    compile group: 'org.mapstruct', name: 'mapstruct-processor', version: '1.2.0.Final'
    compile group: 'org.mapstruct', name: 'mapstruct-jdk8', version: '1.2.0.Final'
    apt 'org.mapstruct:mapstruct-processor:1.2.0.Final'
}


buildscript {
    repositories {
        mavenCentral()
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath("net.ltgt.gradle:gradle-apt-plugin:0.9")
    }
}

確保您已正確配置 build.gradle,如 文檔中所述。

如果使用 Eclipse,您可能需要安裝m2e-apt插件。

它將在 IDE 中為 MapStruct 啟用注釋處理器。

首先很簡單,您需要創建如下界面,

@Mapper(componentModel = "spring")
public interface CompanyMapper {
     @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
     void updateCustomerFromDto(CompanyDto dto, @MappingTarget CompanyBean entity);
}

現在,當您運行應用程序時,它將在 target/generated-source 文件夾中自行生成其實現文件

因此,每當您想使用 CompanyMapper 時,您只需要像我們使用@Mapper(componentModel = "spring")那樣自動裝配它,這樣 spring boot 就可以注入它。

您還需要通過 eclipse 中的以下步驟啟用 Maven 注釋處理:

Step1 :- 右鍵單擊​​項目
Step2 :- 轉到屬性
Step3 : 從側邊欄展開 Maven
Step4 :- 選擇注釋處理
第 5 步:- 選中啟用項目特定設置
Step6 :- 選擇實驗單選按鈕
Step7 :- 申請並關閉

完成 ! 我希望它對某人有幫助。

確保將注釋處理器路徑放在依賴項中。

<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>${java.version}</source> <!-- depending on your project -->
                <target>${java.version}</target> <!-- depending on your project -->
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>${org.mapstruct.version}</version>
                    </path>
                    <!-- other annotation processors -->
                </annotationProcessorPaths>
            </configuration>
        </plugin>

POM.XML

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.customer-service</groupId>
    <artifactId>customer-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>customer-service</name>
    <description>Microservice Client-Facture avec Spring Boot</description>
    <properties>
        <java.version>11</java.version>
        <spring-cloud.version>2021.0.3</spring-cloud.version>
         <org.mapstruct.version>1.4.2.Final</org.mapstruct.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->

        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-ui</artifactId>
            <version>1.5.2</version>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

     <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>1.18.16</version>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
             
                <configuration>
                    <source>17</source> <!-- depending on your project -->
                    <target>17</target> <!-- depending on your project -->
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>1.18.16</version>
                        </path>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                        <!-- other annotation processors -->
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM