spring boot 之使用mapstruct
最近在阅读swagger源码,当看到 springfox.documentation.swagger2.mappers.ModelMapper 类时,无意中看到该类上面使用的 org.mapstruct.Mapper 注解时,对这个注解一时竟想不出个所意然来。便打开百度搜索了一番,有关这个注解的文章不是很多,从这些文章中了解到,这个注解跟JSR 269 有关,下面列出这个注解相关的文章链接。
相关的文章链接:
- mapstruct官网 http://mapstruct.org/
 - mapstruct github网址:https://github.com/mapstruct/mapstruct
 - JSR 269: Pluggable Annotation Processing API https://jcp.org/en/jsr/detail?id=269
 - 插入式注解处理API(Pluggable Annotation Processing API) https://blog.csdn.net/yczz/article/details/34116189
 - MapStruct实体间转换快速入门 https://blog.csdn.net/lx_yoyo/article/details/75061614
 
当看完上面的几篇的文章之后,对这个注解到底起何作用,仍然是一知半解。于是参照上面列表中的 MapStruct实体间转换快速入门 ,当我把工程建好,copy完相关的代码之后,根据文章的提示,执行mvn install(mvn compile)命令之后,没有出现文章中提到的在 target\generated-sources\annotations 会自动生成PeopleMapperImpl.Java 源文件,反到是控制台打印出的日志信息提示编译失败,错误信息如下所示:
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /F:/java.ws.01/springboot-example/example4/src/main/java/com/github/torlight/sbex/PeopleMapper.java:[21,15] No property named "age" exists in source parameter(s). Did you mean "null"?
[ERROR] /F:/java.ws.01/springboot-example/example4/src/main/java/com/github/torlight/sbex/PeopleMapper.java:[32,10] No property named "user.name" exists in source parameter(s). Did you mean "null"?
[INFO] 2 errors
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.951 s
[INFO] Finished at: 2018-08-19T10:52:59+08:00
[INFO] Final Memory: 26M/282M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile (default-compile) on project example4: Compilation failure: Compilation failure:
[ERROR] /F:/java.ws.01/springboot-example/example4/src/main/java/com/github/torlight/sbex/PeopleMapper.java:[21,15] No property named "age" exists in source parameter(s). Did you mean "null"?
[ERROR] /F:/java.ws.01/springboot-example/example4/src/main/java/com/github/torlight/sbex/PeopleMapper.java:[32,10] No property named "user.name" exists in source parameter(s). Did you mean "null"?
[ERROR] -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile (default-compile) on project example4: Compilation failure
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:212)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:862)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:286)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:197)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.apache.maven.plugin.compiler.CompilationFailureException: Compilation failure
at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:972)
at org.apache.maven.plugin.compiler.CompilerMojo.execute(CompilerMojo.java:129)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
... 20 more
[ERROR]
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
当出现上面的错误之后,先是在网上找了一下,但没有找到相关的资料,没办法只能靠自己解决了。查看工程的pom.xml文件,有用到maven-compiler-plugin 插件,看到该插件的配置项中mapstruct-processor ,心里也清楚当maven执行maven-compiler-plugin 插件中相关类的方法时,肯定会执行mapstruct-processor 中相关类的方法。可是不清楚具体会先从那个类的方法开始执行。
没办法,只能根据上面的异常提示信息,在maven源码工程中一路跟踪下来,发现错误源是当执行SourceReference类的getSourceEntries方法时触发的。No property named "age" exists in source parameter(s). Did you mean "null"? 在被转换的实体中找不到age属性,可是在PeopleEntity 实体中本来就存在age属性。原来报错是因为getSourceEntries方法是通过反射读取实体的get方法来获取属性,然后再进行属性比较,怪不得会报错。当找到报错的原因之后,我把目光停留在源码中的注释 //constructor, getters, setters etc. 原来实体中的getter,setter 方法都被省略了。
 package com.github.torlight.sbex;
 public class PeopleEntity {
     private Integer age;
     private String name;
     private String callNumber;
     private String address;
     private String email;
     public PeopleEntity() {
     }
     public PeopleEntity(Integer age, String name, String callNumber, String address, String email) {
         this.age = age;
         this.name = name;
         this.callNumber = callNumber;
         this.address = address;
         this.email = email;
     }
   //constructor, getters, setters etc.
 }

修改之后的代码:
 package com.github.torlight.sbex;
 public class PeopleDTO {
     private String phoneNumber;
     private String address;
     private String email;
     private User  user;
     public PeopleDTO() {
     }
     public PeopleDTO(String phoneNumber, String address, String email, User user) {
         this.phoneNumber = phoneNumber;
         this.address = address;
         this.email = email;
         this.user = user;
     }
     public String getPhoneNumber() {
         return phoneNumber;
     }
     public void setPhoneNumber(String phoneNumber) {
         this.phoneNumber = phoneNumber;
     }
     public String getAddress() {
         return address;
     }
     public void setAddress(String address) {
         this.address = address;
     }
     public String getEmail() {
         return email;
     }
     public void setEmail(String email) {
         this.email = email;
     }
     public User getUser() {
         return user;
     }
     public void setUser(User user) {
         this.user = user;
     }
 }
 package com.github.torlight.sbex;
 public class PeopleEntity {
     private Integer age;
     private String name;
     private String callNumber;
     private String address;
     private String email;
     public PeopleEntity() {
     }
     public PeopleEntity(Integer age, String name, String callNumber, String address, String email) {
         this.age = age;
         this.name = name;
         this.callNumber = callNumber;
         this.address = address;
         this.email = email;
     }
     public Integer getAge() {
         return age;
     }
     public void setAge(Integer age) {
         this.age = age;
     }
     public String getName() {
         return name;
     }
     public void setName(String name) {
         this.name = name;
     }
     public String getCallNumber() {
         return callNumber;
     }
     public void setCallNumber(String callNumber) {
         this.callNumber = callNumber;
     }
     public String getAddress() {
         return address;
     }
     public void setAddress(String address) {
         this.address = address;
     }
     public String getEmail() {
         return email;
     }
     public void setEmail(String email) {
         this.email = email;
     }
 }   
package com.github.torlight.sbex;
public class User {
    private Integer age;
    private String name;
    public User() {
    }
    public User(Integer age, String name) {
        this.age = age;
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
执行mvn install(mvn compile)命令之后,控制台没有提示报错,但在 \target\generated-sources\annotations\ 文件夹下面还是空的,奇怪了? 先执行mvn clean 然后再执行 mvn install(mvn compile)之后,终于出现了PeopleMapperImpl.java 源文件。要确保 target\class 文件夹下面为空时,执行mvn install(mvn compile)命令才能生成java源文件。

示例代码: https://github.com/gittorlight/springboot-example/tree/master/example4
spring boot 之使用mapstruct的更多相关文章
- 从零一起学Spring Boot之LayIM项目长成记(三) 数据库的简单设计和JPA的简单使用。
		
前言 今天是第三篇了,上一篇简单模拟了数据,实现了LayIM页面的数据加载.那么今天呢就要用数据库的数据了.闲言少叙,书归正传,让我们开始吧. 数据库 之前有好多小伙伴问我数据库是怎么设计的.我个人用 ...
 - maven 聚合工程 用spring boot 搭建 spring cloud 微服务 模块式开发项目
		
项目的简单介绍: 项目采用maven聚合工程 用spring boot 搭建 spring cloud的微服务 模块式开发 项目的截图: 搭建开始: 能上图 我少打字 1.首先搭建maven的聚合工程 ...
 - spring boot+mybatis+swagger搭建
		
环境概述 使用的开发工具:idea 2018 3.4 环境:jdk1.8 数据库:MariaDB (10.2.21) 包管理:Maven 3.5 Web容器:Tomcat 8.0 开发机系统:Wind ...
 - Spring boot 、mybatis、swagger、c3p0、redis 和mongodb 整合
		
文件路径: 添加依赖: <?xml version="1.0" encoding="UTF-8"?> <project ...
 - Spring boot 、swagger、c3p0、mybatis和redis 整合
		
文件路径 添加依赖 <?xml version="1.0" encoding="UTF-8"?> <projec ...
 - Spring Boot 、mybatis 、swagger 和 c3p0 整合
		
文件路径如下 添加依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=" ...
 - Spring boot 、mybatis 和 swagger 整合
		
文件路径 添加依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...
 - spring-boot-plus是易于使用,快速,高效,功能丰富,开源的spring boot 脚手架.
		
Everyone can develop projects independently, quickly and efficiently! spring-boot-plus是一套集成spring bo ...
 - 从零搭建Spring Boot脚手架(1):开篇以及技术选型
		
1. 前言 目前Spring Boot已经成为主流的Java Web开发框架,熟练掌握Spring Boot并能够根据业务来定制Spring Boot成为一个Java开发者的必备技巧,但是总是零零碎碎 ...
 
随机推荐
- T51071 Tony到死都想不出の数学题
			
T51071 Tony到死都想不出の数学题 自己摘的题出了数据挂一下链接 \(a, b\) 均为整数 设 \(M(a)\) 为满足 \((a + b) | ab\) 的 \(b\) 的个数, 求 \( ...
 - classpath 及读取 properties 文件
			
java代码中获取项目的静态文件,如获取 properties 文件内容是必不可少的. Spring 下只需要通过 @Value 获取配置文件值 <!-- 资源文件--> <util ...
 - 我购买byd的几点逻辑
			
1.伯克希尔哈撒韦长期看好byd不是无道理的,每次转型都是那么的成功,说明管理层很好. 2.2015年6月员工持股计划均价55元,目前48元. 3.新能源汽车龙头. 4.云轨解决了小城市建设地铁过于浪 ...
 - PHP7 学习笔记(一)Ubuntu 16.04 编译安装Nginx-1.10.3、 PHP7.0.9、Redis3.0 扩展、Phalcon3.1 扩展、Swoole1.9.8 扩展、ssh2扩展(全程编译安装)
			
==================== PHP 7.0 编译安装================== wget http://cn2.php.net/get/php-7.0.9.tar.bz2/fr ...
 - 发现IE 9的一个独有的小bug,并附解决方案
			
在最近的项目中,解决了一些浏览器兼容方面的bug,这篇主要描述在IE 9在渲染值为auto的overflow-x属性时,所产生的专属bug及解决办法. 1.问题描述 在做一个收货地址管理静态页面的时候 ...
 - 图片src拼接后台返回ID
			
本文地址:http://www.cnblogs.com/veinyin/p/8507403.html 在学习 CSS 时只了解了给固定地址,但是如果给的是一个需要拼接的地址就蒙了,以下是基于 Vue ...
 - nginx配置php时fastcgi_pass参数问题
			
更多内容推荐微信公众号,欢迎关注: 在配置nginx的时候,fastcgi_pass的配置问题,如下所示: location ~ \.php$ { root /home/wwwroot; fastcg ...
 - oracle06
			
1. Oracle的体系结构 - 了解 1.1. Oracle数据库和Oracle实例 Oracle 服务器软件部分由两大部分组成, Oracle 数据库 和 Oracle 实例. 两者的解释如下: ...
 - UNIX环境高级编程 第13章 守护进程
			
守护进程daemon是一种生存周期很长的进程.它们通常在系统引导时启动,在系统关闭时终止.守护进程是没有终端的,它们一直在后台运行. 守护进程的特征 在Linux系统中,可以通过命令 ps -efj ...
 - ActiveMQ实现消息的发送与接受
			
activemq是apache的一个JMS接口的实现产品,java中定义了JMS规范,虽然RocketMQ,kafka现在比较火,但是还是建议先学一下activeMQ再学其他两个就容易很多 首先可以下 ...