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 方法都被省略了。
1 package com.github.torlight.sbex; 2 3 public class peopleentity { 4 private integer age; 5 private string name; 6 private string callnumber; 7 private string address; 8 private string email; 9 10 public peopleentity() { 11 12 } 13 14 public peopleentity(integer age, string name, string callnumber, string address, string email) { 15 this.age = age; 16 this.name = name; 17 this.callnumber = callnumber; 18 this.address = address; 19 this.email = email; 20 } 21 22 //constructor, getters, setters etc. 23 24 }
修改之后的代码:
1 package com.github.torlight.sbex; 2 3 public class peopledto { 4 5 private string phonenumber; 6 private string address; 7 private string email; 8 private user user; 9 10 public peopledto() { 11 12 } 13 14 public peopledto(string phonenumber, string address, string email, user user) { 15 this.phonenumber = phonenumber; 16 this.address = address; 17 this.email = email; 18 this.user = user; 19 } 20 21 public string getphonenumber() { 22 return phonenumber; 23 } 24 25 public void setphonenumber(string phonenumber) { 26 this.phonenumber = phonenumber; 27 } 28 29 public string getaddress() { 30 return address; 31 } 32 33 public void setaddress(string address) { 34 this.address = address; 35 } 36 37 public string getemail() { 38 return email; 39 } 40 41 public void setemail(string email) { 42 this.email = email; 43 } 44 45 public user getuser() { 46 return user; 47 } 48 49 public void setuser(user user) { 50 this.user = user; 51 } 52 53 }
1 package com.github.torlight.sbex; 2 3 public class peopleentity { 4 private integer age; 5 private string name; 6 private string callnumber; 7 private string address; 8 private string email; 9 10 public peopleentity() { 11 12 } 13 14 public peopleentity(integer age, string name, string callnumber, string address, string email) { 15 this.age = age; 16 this.name = name; 17 this.callnumber = callnumber; 18 this.address = address; 19 this.email = email; 20 } 21 22 public integer getage() { 23 return age; 24 } 25 26 public void setage(integer age) { 27 this.age = age; 28 } 29 30 public string getname() { 31 return name; 32 } 33 34 public void setname(string name) { 35 this.name = name; 36 } 37 38 public string getcallnumber() { 39 return callnumber; 40 } 41 42 public void setcallnumber(string callnumber) { 43 this.callnumber = callnumber; 44 } 45 46 public string getaddress() { 47 return address; 48 } 49 50 public void setaddress(string address) { 51 this.address = address; 52 } 53 54 public string getemail() { 55 return email; 56 } 57 58 public void setemail(string email) { 59 this.email = email; 60 } 61 62 }
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
上一篇: Python基于百度云文字识别API
推荐阅读
-
Spring Boot项目实战之拦截器与过滤器
-
spring boot 使用Aop通知打印控制器请求报文和返回报文问题
-
[Spring Boot]使用自定义注解统一请求返回值
-
JSP 开发之Spring BeanUtils组件使用
-
Spring Boot 入门之消息中间件的使用
-
Spring Boot使用AOP防止重复提交的方法示例
-
在Spring Boot中使用swagger-bootstrap-ui的方法
-
Spring JdbcTemplate之使用详解
-
在 Spring Boot 项目中使用 activiti
-
spring-boot-2.0.3不一样系列之源码篇 - run方法(三)之createApplicationContext,绝对有值得你看的地方