spring boot 之使用mapstruct


  最近在閱讀swagger源碼,當看到 springfox.documentation.swagger2.mappers.ModelMapper 類時,無意中看到該類上面使用的 org.mapstruct.Mapper 注解時,對這個注解一時竟想不出個所意然來。便打開百度搜索了一番,有關這個注解的文章不是很多,從這些文章中了解到,這個注解跟JSR 269 有關,下面列出這個注解相關的文章鏈接。


 相關的文章鏈接:

  1.  mapstruct官網 http://mapstruct.org/
  2.  mapstruct github網址:https://github.com/mapstruct/mapstruct
  3. JSR 269: Pluggable Annotation Processing API  https://jcp.org/en/jsr/detail?id=269
  4. 插入式注解處理API(Pluggable Annotation Processing API)  https://blog.csdn.net/yczz/article/details/34116189
  5. 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM