我无法在我的 Spring 项目中添加 mapstruct
I can't add mapstruct in my Spring project
我尝试在我的 Spring 项目中添加 mapstruct 映射器。
我有一个用户实体。我需要在管理面板中显示用户列表。为此,我做了 DTO UserForAdmin、映射器 UserMapper 和其余控制器 AdminRestController。当我尝试获取 UserMapper 时出现错误。
我尝试了两种方式:
- Mappers.getMapper(UserMapper.class)
我收到错误
java.lang.ClassNotFoundException: Cannot find implementation for
ru.project.mapper.UserMapper
- 自动装配
我收到错误
Error starting ApplicationContext. To display the conditions report
re-run your application with 'debug' enabled. 2019-07-17 15:47:07.886
ERROR 13652 --- [ restartedMain]
o.s.b.d.LoggingFailureAnalysisReporter :
*************************** APPLICATION FAILED TO START
Description:
Field userMapper in ru.project.controller.rest.AdminRestController
required a bean of type 'ru.project.mapper.UserMapper' that could not
be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'ru.project.mapper.UserMapper' in
your configuration.
这是我的源代码。
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。
使用 @Mapper(componentModel = "spring")
- 启用 di。
运行 mvn package
命令 - 它创建实现 class。
@Autowired
映射器接口和使用。
(java中的方法名首字母要小写)
找不到 ru.project.mapper.UserMapper 的实现,这意味着 UserMapper 必须由某些 class 实现。
如public Class UserMapperImple 实现 UserMapper {XXXXXXX}
然后 Mappers.getMapper("UserMapper") 将获得 UserMapperImple。
考虑在您的配置中定义一个 'ru.project.mapper.UserMapper' 类型的 bean。这意味着 @Mapper 不起作用;我建议你检查 spring-config.xml。 ApplicationContext 可能不会扫描此包。
希望能帮到你:)
你需要使用@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;
并且我假设 User 和 UserForAdmin 具有相同的字段名称
在此之后 运行 mvn clean compile
和来源将被生成
使用注释 @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
上试过了
有一种简单的解决方法。
在您的映射器 class 处,使用 @Mapper(componentModel = "spring")
和来自终端的 运行 mvn clean install
命令。
或者在 STS/Eclipse 的情况下,转到 Project> 运行 As> maven clean
然后运行 Project> 运行 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>
我尝试在我的 Spring 项目中添加 mapstruct 映射器。
我有一个用户实体。我需要在管理面板中显示用户列表。为此,我做了 DTO UserForAdmin、映射器 UserMapper 和其余控制器 AdminRestController。当我尝试获取 UserMapper 时出现错误。
我尝试了两种方式:
- Mappers.getMapper(UserMapper.class)
我收到错误
java.lang.ClassNotFoundException: Cannot find implementation for ru.project.mapper.UserMapper
- 自动装配
我收到错误
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2019-07-17 15:47:07.886 ERROR 13652 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
*************************** APPLICATION FAILED TO START
Description:
Field userMapper in ru.project.controller.rest.AdminRestController required a bean of type 'ru.project.mapper.UserMapper' that could not be found.
The injection point has the following annotations: - @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'ru.project.mapper.UserMapper' in your configuration.
这是我的源代码。
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。
使用 @Mapper(componentModel = "spring")
- 启用 di。
运行 mvn package
命令 - 它创建实现 class。
@Autowired
映射器接口和使用。
(java中的方法名首字母要小写)
找不到 ru.project.mapper.UserMapper 的实现,这意味着 UserMapper 必须由某些 class 实现。
如public Class UserMapperImple 实现 UserMapper {XXXXXXX}
然后 Mappers.getMapper("UserMapper") 将获得 UserMapperImple。
考虑在您的配置中定义一个 'ru.project.mapper.UserMapper' 类型的 bean。这意味着 @Mapper 不起作用;我建议你检查 spring-config.xml。 ApplicationContext 可能不会扫描此包。
希望能帮到你:)
你需要使用@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;
并且我假设 User 和 UserForAdmin 具有相同的字段名称
在此之后 运行 mvn clean compile
和来源将被生成
使用注释 @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
上试过了有一种简单的解决方法。
在您的映射器 class 处,使用 @Mapper(componentModel = "spring")
和来自终端的 运行 mvn clean install
命令。
或者在 STS/Eclipse 的情况下,转到 Project> 运行 As> maven clean
然后运行 Project> 运行 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>