【问题标题】:I can't add mapstruct in my Spring project我无法在我的 Spring 项目中添加 mapstruct
【发布时间】:2019-07-17 12:52:46
【问题描述】:

我尝试在我的 Spring 项目中添加 mapstruct 映射器。

我有一个用户实体。我需要在管理面板中显示用户列表。为此,我做了 DTO UserForAdmin、映射器 UserMapper 和休息控制器 AdminRestController。当我尝试获取 UserMapper 时出现错误。

我尝试了两种方法:

  1. Mappers.getMapper(UserMapper.class)

我得到错误

java.lang.ClassNotFoundException:找不到实现 ru.project.mapper.UserMapper

  1. 自动接线

我收到错误

启动 ApplicationContext 时出错。显示条件报告 在启用“调试”的情况下重新运行您的应用程序。 2019-07-17 15:47:07.886 错误 13652 --- [restartedMain] o.s.b.d.LoggingFailureAnalysisReporter:

***************************应用程序启动失败


说明:

ru.project.controller.rest.AdminRestController 中的字段 userMapper 需要一个 'ru.project.mapper.UserMapper' 类型的 bean,它不能 找到了。

注入点有以下注解: - @org.springframework.beans.factory.annotation.Autowired(required=true)

行动:

考虑定义一个“ru.project.mapper.UserMapper”类型的bean 你的配置。

这是我的源代码。

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 http://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.1.6.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>ru.project</groupId>
    <artifactId>project</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>project</name>
    <description>The project is project of resourse for investors.</description>

    <properties>
        <java.version>12</java.version>
        <org.mapstruct.version>1.3.0.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-mail</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</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.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        </dependency>
        <dependency>
            <groupId>org.modelmapper</groupId>
            <artifactId>modelmapper</artifactId>
            <version>2.3.5</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </path>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>                 
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

我的界面UserMapper:

package ru.project.mapper;

import java.util.List;

import org.mapstruct.Mapper;
import ru.project.domain.User;
import ru.project.dto.UserForAdmin;

@Mapper
//@Mapper(componentModel = "spring")
public interface UserMapper {

    UserForAdmin UserToUserForAdmin(User user);

    List<UserForAdmin> UserListToUserForAdminList(List<User> user);


}

我的 RestController:

package ru.project.controller.rest;

import java.util.List;

import org.mapstruct.factory.Mappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import ru.project.dto.UserForAdmin;
import ru.project.mapper.UserMapper;
import ru.project.service.UserService;

@RestController
public class AdminRestController {

    @Autowired
    private UserService userService;

    //@Autowired
    //private UserMapper userMapper;

    @GetMapping("/admin/users")
    public List<UserForAdmin> findAllUsers(){

        UserMapper userMapper = Mappers.getMapper(UserMapper.class);

        return userMapper.UserListToUserForAdminList(userService.findAll()); 
    }

}

我想使用 Awtowired。

【问题讨论】:

    标签: spring autowired spring-restcontroller mapper mapstruct


    【解决方案1】:

    你需要使用@Mapper(componentModel="spring")

    package ru.project.mapper;
    
        import java.util.List;
    
        import org.mapstruct.Mapper;
        import ru.project.domain.User;
        import ru.project.dto.UserForAdmin;
    
            @Mapper(componentModel = "spring")
            public interface UserMapper {
    
                UserForAdmin UserToUserForAdmin(User user);
    
                List<UserForAdmin> UserListToUserForAdminList(List<User> user);
    
            }
    

    并在下面的 AdminRestController 中使用

    @Autowired  
    private UserMapper userMapper;
    

    我假设 UserUserForAdmin 具有相同的字段名称 在此运行后mvn clean compile 将生成源代码

    【讨论】:

      【解决方案2】:

      使用注解@Mapper(componentModel = "spring") 的替代方法是将组件模型作为编译器参数添加到插件中。注释有效,但烦人的事情可能是必须将其添加到您创建的每个映射器中。您添加一次的编译器参数适用于项目中的所有映射器。下面是一个带有 componentModel 编译器参数的插件定义示例。

      <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>
                              <path>
                                  <groupId>org.mapstruct</groupId>
                                  <artifactId>mapstruct-processor</artifactId>
                                  <version>${org.mapstruct.version}</version>
                              </path>
                              <path>
                                  <groupId>org.projectlombok</groupId>
                                  <artifactId>lombok</artifactId>
                                  <version>${org.projectlombok.version}</version>
                              </path>
                          </annotationProcessorPaths>
                          <compilerArgs>
                              <arg>-Amapstruct.defaultComponentModel=spring</arg>
                          </compilerArgs>
                      </configuration>
                  </plugin>
      

      我在 1.3.0.Final 以及 1.3.1.Final 和 sping boot 2.1.7/8/9 版本上都试过这个

      【讨论】:

        【解决方案3】:

        使用@Mapper(componentModel = "spring") - 启用二。 运行mvn package 命令 - 它创建实现类。 @Autowiredmapper接口和使用。

        (java中的方法名开头字母应该小写)

        【讨论】:

        • 如何在 Spring Tool Suite 4(Eclipse) 中运行mvn package 命令?
        • 使用终端或我记得(我有一段时间没有使用 eclipse):项目 > 运行方式 > maven build
        • 我找到了如何在 STS 中运行 mvn package。创建了实现类。 Mappers.getMapper 有效。但自动接线不起作用。
        • 需要用@Mapper(componentModel = "spring")注解mapper接口
        【解决方案4】:

        有一个简单的解决方案。

        在您的映射器类中,使用@Mapper(componentModel = "spring")

        然后从终端运行mvn clean install 命令。

        或者在 STS/Eclipse 的情况下,转到 Project> Run As> maven clean

        然后运行Project> Run As> maven install

        你的映射器 Impl 将被生成!

        注意:关于插件

        如果您同时使用以下两个依赖项,则无需在 pom.xml 文件中使用插件

                <dependency>
                    <groupId>org.mapstruct</groupId>
                    <artifactId>mapstruct</artifactId>
                    <version>${org.mapstruct.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.mapstruct</groupId>
                    <artifactId>mapstruct-processor</artifactId>
                    <version>${org.mapstruct.version}</version>
                </dependency>
        

        属性会是这样的;

            <properties>
                <java.version>11</java.version>
                <org.mapstruct.version>1.3.1.Final</org.mapstruct.version>
            </properties>
        

        【讨论】:

          【解决方案5】:

          找不到 ru.project.mapper.UserMapper 的实现,这意味着 UserMapper 必须由某个类实现。

          如公共类UserMapperImple实现UserMapper {XXXXXXX}

          那么 Mappers.getMapper("UserMapper") 将获得 UserMapperImple。

          考虑在您的配置中定义一个“ru.project.mapper.UserMapper”类型的bean。这意味着@Mapper 不起作用;我建议你检查 spring-config.xml。 ApplicationContext 可能不会扫描这个包。

          希望能帮到你:)

          【讨论】:

          • 在哪里可以找到 spring-config.xml?我还没有配置。
          • 文件名可能与 "spring-config.xml" 不同。它可能像这样: -扫描>
          猜你喜欢
          • 2014-07-12
          • 1970-01-01
          • 2011-03-27
          • 1970-01-01
          • 1970-01-01
          • 2016-09-24
          • 1970-01-01
          • 2021-04-01
          • 1970-01-01
          相关资源
          最近更新 更多