MapStruct 实现在 Spring 引导 Web 应用程序中不起作用
MapStruct implementation is not working in Spring Boot Web Application
我是 Spring 引导和 MapStruct 工具的新手。
早些时候,一个项目(由其他团队使用这些技术编写)没有启动。然后,我在 Mapper Abstract Class 中做了一些更改,但现在 mapper 对象在应用程序启动时变为 null。
映射器摘要Class:
@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 class
@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 启动应用程序 class 在包 org
中,那么它将选择 UserAndEmployeeMapperImpl
。否则确保 spring 配置选择 UserAndEmployeeMapperImpl
.
如果上面的所有内容都正确设置并且您通过 IDE 启动应用程序,请确保 target/generated-sources
或 Gradle 的替代项是您的来源的一部分并被选中向上。查看 IDE Support 以确保您已正确设置 IDE 的注解处理器发现。例如,IntelliJ 不会使用您当前的设置调用 MapStruct Annotation Processor,它不会从 Maven 编译器中获取 annotationProcessorPaths
。
将抽象 class 作为接口对我有用。
public interface UserAndEmployeeMapper {
springfox-swagger2 依赖项正在加载旧版本的 mapstruct 并在 pom.xml 中添加特定版本的 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>
就我而言,我认为错误是由于不完整 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,如 the docs.
中所述
如果使用 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 注释处理:
第 1 步:- 右键单击项目
第 2 步:- 转到属性
第 3 步:从侧边栏展开 Maven
Step4 :- Select 注释处理
第 5 步:- 选中启用项目特定设置
Step6 :- Select 实验单选按钮
Step7 :- 应用并关闭
完成!
我希望它对某人有所帮助。
在 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)
确保将注释处理器路径放入依赖项中。
<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>
我是 Spring 引导和 MapStruct 工具的新手。
早些时候,一个项目(由其他团队使用这些技术编写)没有启动。然后,我在 Mapper Abstract Class 中做了一些更改,但现在 mapper 对象在应用程序启动时变为 null。
映射器摘要Class:
@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 class
@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 启动应用程序 class 在包 org
中,那么它将选择 UserAndEmployeeMapperImpl
。否则确保 spring 配置选择 UserAndEmployeeMapperImpl
.
如果上面的所有内容都正确设置并且您通过 IDE 启动应用程序,请确保 target/generated-sources
或 Gradle 的替代项是您的来源的一部分并被选中向上。查看 IDE Support 以确保您已正确设置 IDE 的注解处理器发现。例如,IntelliJ 不会使用您当前的设置调用 MapStruct Annotation Processor,它不会从 Maven 编译器中获取 annotationProcessorPaths
。
将抽象 class 作为接口对我有用。
public interface UserAndEmployeeMapper {
springfox-swagger2 依赖项正在加载旧版本的 mapstruct 并在 pom.xml 中添加特定版本的 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>
就我而言,我认为错误是由于不完整 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,如 the docs.
中所述如果使用 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 注释处理:
第 1 步:- 右键单击项目
第 2 步:- 转到属性
第 3 步:从侧边栏展开 Maven
Step4 :- Select 注释处理
第 5 步:- 选中启用项目特定设置
Step6 :- Select 实验单选按钮
Step7 :- 应用并关闭
完成! 我希望它对某人有所帮助。
在 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)
确保将注释处理器路径放入依赖项中。
<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>