我正在关注这个关于部分更新的教程。按照指示,我创建了带有适当注释的映射器接口。
这是映射器
@Mapper(componentModel = "spring")
public interface UserEntityMapper {
@Mapping(source = "password", target = "password")
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
void updatePasswordFromDTO(PasswordResetRequest dto, @MappingTarget User entity);
}
根据教程,
@Mapper(componentModel = "spring")
生成映射器作为Spring bean,可以通过@Autowired
检索。
但是当我尝试在服务层中做同样的事情时
class
,
@Service
@Transactional
public class AccountServiceImpl implements IAccountService {
...
@Autowired
private UserEntityMapper userMapper;
...
}
我收到此错误,我的应用程序无法启动。
***************************
APPLICATION FAILED TO START
***************************
Description:
Field userMapper in com.application.services.AccountServiceImpl required a bean of type 'com.application.mappers.UserEntityMapper' 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 'com.application.mappers.UserEntityMapper' 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 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.5.5</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.myproject</groupId>
<artifactId>myproject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>authentication-template</name>
<description>Description</description>
<properties>
<java.version>11</java.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-validation</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>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.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.4.2.Final</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
我也尝试了这些不同的解决方案,但结果相同。
这是
@SpringBootApplication
文件。
@SpringBootApplication
@PropertySources(value = {
@PropertySource("classpath:mail.properties"),
@PropertySource("classpath:messages.properties"),
@PropertySource("classpath:security.properties")
})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
项目的包结构
请帮忙,谢谢:)
如果您提供的 pom.xml 是最新版本,我认为您错过了实际根据您的定义生成 MapStruct 映射器的步骤。您需要将其定义为构建设置的一部分,如此处所述 https://mapstruct.org/documentation/installation/
您需要将该部分添加到构建 - 插件部分
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source> <!-- depending on your project -->
<target>1.8</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>
如果映射器已成功生成,还请检查您的目标/生成的文件夹
编辑:
运行构建后,请验证您的 Maven 构建输出文件夹 target/ generated-sources 实际上包含一些为 MapStruct 生成的映射器。另请观察您的 Maven 构建日志输出以获取已生成 MapStruct 映射器的提示。
如果没有生成映射器,则构建设置中的某些内容有问题,我们需要仔细查看您的日志输出。
但是如果生成了映射器,您应该检查是否具有 spring 的 @Component 注释,并且它们位于包中,即位于 Springs 的 bean 扫描路径上。
添加到插件:
<compilerArgs>
<compilerArg>
-Amapstruct.defaultComponentModel=spring
</compilerArg>
</compilerArgs>
我有如下的依赖关系,一切都很好。
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.4.2.Final</version>
</dependency>
以及部分插件。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<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>1.4.2.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
您可以研究一些建议。首先检查mvn生成的类中是否有@Component。
我能够按照以下步骤完成这项工作,而且我还使用了 lombok & mapstruct 以及 maven
第1步:添加lombok和mapstruct依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
第2步:由于mapstruct和lombok都是基于注解处理的。在maven构建插件部分添加配置,如果使用IntelliJ IDEA,则不需要此步骤,通过在IDE设置中启用注释处理。
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass></mainClass> <!-- FQN of class with main method
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
第3步:Mapper类应该使用@Mapper注释进行注释
@Mapper(componentModel = "spring")
@Service
public interface PersonMapper {
// add appropriate mapper methods
}
第3步:更新maven项目并运行
mvn 全新安装
运行应用程序。在目标文件夹中将有由mapstruct生成的PersonMapperImpl.java。
我知道,我来晚了。对于延迟回答问题表示歉意。让我们深入了解 MapStruct 的配置。
实际问题在于配置。我按照以下步骤成功使用 Spring Boot 配置 MapStruct。
首先在
mapstruct
中添加pom.xml
依赖。
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<scope>provided</scope> <!-- Required -->
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.5.Final</version>
</dependency>
注意: 确保将
设置为<scope>provided</scope>
。没有那个lombok
对我来说就不起作用。@Builder
由于
mapstruct
需要注释处理,所以我们需要将插件添加到我们的pom.xml
中。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
注意:
是lombok-mapstruct-binding
和Lombok
所必需的,以便他们能够合作。Mapstruct
确保您的 IDE 中启用了注释处理。您可以检查这些链接以获取 IntelliJ Idea 和 Eclipse/STS
完成后,您可以创建
mapper interface
。
import static org.mapstruct.MappingConstants.ComponentModel.SPRING;
@Mapper(componentModel = SPRING)
public interface UserMapper {
UserModel dtoToModel(UserDTO userDto);
}
那么
mapper
就可以轻松@Autowired
。
@Service
public class UserService {
private final UserMapper userMapper;
@Autowired
public UserService(UserMapper userMapper) {
this.userMapper= userMapper;
}
// Business logic
}
我希望这会有所帮助。谢谢和问候。