基於Lombok集成springboot遇到的坑
Lombok集成springboot遇到的坑
最近有同事在spring boot中用Lombok @Data註解時遇到瞭一個奇怪的問題,然後有幸一起研究瞭一下,把研究成果記錄下來。
問題
先上代碼:
@Data public abstract class TestAbstract { private RedisTemplate redisTemplate; public TestAbstract(RedisTemplate redisTemplate) { this.redisTemplate = redisTemplate; } }
@Data public class TestChild extends TestAbstract { @Autowired public TestChild(RedisTemplate redisTemplate) { super(redisTemplate); } }
上面的代碼在spring boot 2.0.2版本可以正常運行,但在2.0.3版本卻編譯錯誤。
Error:(13, 1) java: TestAbstract() 在 com.brotherj.learn.TestAbstract 中是private 訪問控制
查看瞭pom.xml文件後發現lombok的版本號是從spring boot繼承而來:
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
然後又查看瞭spring boot pom.xml中的lombok版本號,發現從spring boot 2.0.3版本開始使用瞭lombok 1.16.22,而2.0.2版本使用的是1.16.20版本。
#2.0.2 <lombok.version>1.16.20</lombok.version> #2.0.3 <lombok.version>1.16.22</lombok.version>
於是修改pom.xml版本號之後,問題解決。
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> <version>1.16.20</version> </dependency>
原因
問題解決後,決定研究一下具體的原因,由於Lombok隻是依靠可插件化的Java自定義註解處理API(JSR 269: Pluggable Annotation Processing API)來實現在Javac編譯階段利用“Annotation Processor”對自定義的註解進行預處理後生成真正在JVM上面執行的“Class文件”。
所以應該時兩個版本下編譯生成的class文件不同,於是比較瞭一下兩個版本下編譯後的class文件。
public TestAbstract(RedisTemplate redisTemplate) { this.redisTemplate = redisTemplate; } //1.16.22會生成一個private的構造方法,而1.16.20不會生成 private TestAbstract() { } @Autowired public TestChild(RedisTemplate redisTemplate) { super(redisTemplate); } private TestChild() { }
看到這裡一切就都清楚瞭,是類加載順序導致的問題。
先復習一下類加載順序:(靜態變量、靜態初始化塊)–>(變量、初始化塊)–> 構造器。如果有父類,加載順序是:父類static方法 –> 子類static方法 –> 父類構造方法- -> 子類構造方法 。
也就是說,當加載TestChild類時先加載類TestAbstract的構造方法,而類TestAbstract的空參構造為private,於是報瞭訪問控制的錯誤。
springboot引入Lombok
傳統的寫法,要寫一串串的get()、set()方法等等
現引入Lombok
pom.xml引入
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
引入後發現,在實體類上面使用@Data找不到import的包
網上巴拉巴拉,發現是springBoot的版本和import的版本不統一,加上
<optional>true</optional>
提示版本信息,改為可用的版本即可。修正後如下:
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> <version>1.18.2</version> </dependency>
終於可以正常導入^_^
延伸閱讀(1):
idea安裝Lombok插件
File——Settings——Plugins——Marketplact
延伸閱讀(2):
常見參數
@Setter
註解在類或字段,註解在類時為所有字段生成setter方法,註解在字段上時隻為該字段生成setter方法。@Getter
使用方法同上,區別在於生成的是getter方法。@ToString
註解在類,添加toString方法。@EqualsAndHashCode
註解在類,生成hashCode和equals方法。@NoArgsConstructor
註解在類,生成無參的構造方法。@RequiredArgsConstructor
註解在類,為類中需要特殊處理的字段生成構造方法,比如final和被@NonNull註解的字段。@AllArgsConstructor
註解在類,生成包含類中所有字段的構造方法。@Data
註解在類,為類的所有字段註解@ToString、@EqualsAndHashCode、@Getter的便捷方法,同時為所有非final字段註解@Setter。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Spring Boot整合Lombok的方法詳解
- 使用maven開發springboot項目時pom.xml常用配置(推薦)
- Lombok如何快速構建JavaBean與日志輸出
- Spring Boot教程之提高開發效率必備工具lombok
- idea 在springboot中使用lombok插件的方法