IDEA編寫SpringBoot項(xiàng)目時(shí)使用Lombok報(bào)錯“找不到符號”的原因和解決
概述|背景
報(bào)錯發(fā)生背景:在SpringBoot項(xiàng)目中引入Lombok依賴并使用后出現(xiàn)"找不到符號"的問題。
本文討論在上述背景下發(fā)生的報(bào)錯原因和解決辦法,如果僅為了解決BUG不論原因直接通過目錄跳到【解決方法】,如果發(fā)生背景不同請找其他博文尋求解決。
Lombok"找不到符號"代碼報(bào)錯一般位置:
1.代碼: log.info("日志內(nèi)容.."); (使用了注解@Slf4j)
2.代碼:class.getX(); (使用了注解@Data)
報(bào)錯解析
1.為什么會出現(xiàn)“找不到符號”的報(bào)錯呢?
我們遇到這個(gè)報(bào)錯時(shí)一般都會想到:“難道是這個(gè)變量沒有定義?”,但是轉(zhuǎn)念一想我們所引用的是Lombok給我們提供的變量。
所以,我們應(yīng)該去探索Lombok內(nèi)部,我們在使用log(log.info("日志內(nèi)容.."))變量時(shí),到底發(fā)生了什么。
實(shí)際上,當(dāng)我們編寫了代碼:log.info("日志內(nèi)容.."),在項(xiàng)目編譯時(shí)遇到log變量,會發(fā)生的事情是自動幫我們補(bǔ)充了代碼:private static final Logger log = LoggerFactory.getLogger(...); 向我們提供了log這個(gè)變量引用。
所以,如果這段“自動生成的代碼”沒有自動生成的話,那么log變量自然就找不到,報(bào)錯"找不到符號"那也就合理解釋了。
當(dāng)然,代碼:class.getX(); 原理也是一樣的,只不過自動生成的代碼不同罷了(這段代碼自動生成的是getter函數(shù))。
2.自動生成代碼的時(shí)機(jī)?
當(dāng)我們明白了會報(bào)“找不到符號”的原因就是該自動生成的代碼沒有生成后,我們就該研究一下“使用lombok時(shí)何時(shí)幫我們自動生成代碼”。
我們在使用Lombok時(shí)一般都會在所在類上添加"lombok相關(guān)注解"。
例如:想使用日志log.info(),我們就該聲明注解"@Slf4j",當(dāng)想要自動給類中所有字段添加Getter和Setter函數(shù)時(shí)就該聲明"@Data"對吧。
實(shí)際上這些注解就會成為自動生成代碼位置的錨點(diǎn)。
當(dāng)項(xiàng)目代碼編譯時(shí)遇到這些注解,“lombok注解處理器”就會識別并生成相應(yīng)代碼。
3.注解處理器-最終解釋
最終我們會把問題聚焦在"注解處理器是否正確加載"的問題上來。
因?yàn)槿绻鹟ombok注解處理器沒有正確加載,那么當(dāng)代碼編譯時(shí)遇到"lombok變量"自然就沒有辦法識別。
所以,我們下面我們的解決方案就是“讓注解處理器正確工作”。
解決方法
IDEA配置解決
添加VM選項(xiàng)-D jps.track.ap.dependencies=false
這是目前網(wǎng)絡(luò)上熱門的解決方法,但這是一種“回避型”的解決方案,在低版本的SpringBoot項(xiàng)目中有效,但是在高版本3.x中卻不一定有效。
方法解釋:
1. 首先我們應(yīng)該知道一件事:IDEA(IntelliJ IDEA)自帶了Lombok插件,正常情況下我們在IDEA中編寫"lombok代碼"是能夠正常運(yùn)行(能正常“自動生成代碼”)的。
2. 當(dāng)我們在項(xiàng)目Pom中引入了Lombok依賴之后,Lombok 注解處理器會在編譯時(shí)被 Maven 加載并執(zhí)行,生成 Lombok 注解(如 @Slf4j, @Getter, @Setter)所需要的代碼。但是引入后IDEA自帶的Lombok插件優(yōu)先級低于Lombok依賴提供的注解處理器。
3. 所以當(dāng)引入Lombok依賴后,Maven代碼編譯時(shí)會優(yōu)先尋找Lombok依賴提供的注解處理器(追蹤依賴),如果沒有,直接報(bào)錯“找不到符號”,而不是去使用IDEA自帶的插件去生成代碼。
4.上面這個(gè)參數(shù)通過禁用 IDEA 的依賴追蹤機(jī)制,讓編譯過程 忽略 Maven 構(gòu)建時(shí)依賴檢查失敗的情況。這相當(dāng)于告訴 IDEA:“不要強(qiáng)制檢查這些注解處理器的依賴,不要因?yàn)?Maven 的編譯失敗而阻止代碼編譯。”
5. 這樣一來,即使 Maven 沒有找到注解處理器,IDEA 插件仍然可以繼續(xù)使用,并且 Lombok 的相關(guān)代碼仍然可以通過 IDE 插件自動生成,從而避免報(bào)錯。
總結(jié):添加VM選項(xiàng)參數(shù)jps.track.ap.dependencies=false,實(shí)際上并沒有解決根本問題,只是有忽略了問題導(dǎo)致的編譯終止,讓編譯繼續(xù),使得IDEA的lombok插件可以兜底解決。
(并非所有IDE都默認(rèn)支持lombok,所以這種解決方案理論上并不是最好的)
Pom配置插件解決
合理的解決方案應(yīng)該是我們到Pom文件中配置Lombok的注解處理器。
<!-- pom.xml --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <annotationProcessorPaths> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>版本號需要和boot版本匹配</version> </path> </annotationProcessorPaths> </configuration> </plugin>
配置好記得"clean"一下,然后重新maven編譯,運(yùn)行。
正確配置后,當(dāng)Maven編譯時(shí)就能正確加載到Lombok注解處理器,使得"lombok代碼"能正常生成,避免報(bào)錯發(fā)生。
值得注意的是:在配置如上插件的時(shí)候lombok版本最好填一下<version>版本號</version>。
如果不顯示填的話,大概率會從maven遠(yuǎn)程倉庫調(diào)用下載最新版或穩(wěn)定版的Lombok,自動下載的版本不一定和你SpringBoot項(xiàng)目版本兼容,依然會報(bào)錯。
所以,請到spring-boot-dependencies.pom中查看boot項(xiàng)目版本對應(yīng)的Lombok版本。
文件查找路徑/方法:
最后總結(jié):
1. 問題的核心就在于Lombok注解處理器沒有被正確加載或配置,導(dǎo)致Maven在編譯過程中報(bào)錯,無法生成相應(yīng)的代碼。
2. 盡管使用VM選項(xiàng)參數(shù) -Djps.track.ap.dependencies=false
可以避免報(bào)錯,但最好是確保Maven的Lombok注解處理器配置正確,以確保Maven構(gòu)建過程和IDEA插件共同協(xié)作,使得項(xiàng)目在任何構(gòu)建環(huán)境下都能正確生成代碼。
延申出的問題
當(dāng)我們解決掉了"找不到符號"的報(bào)錯后,很可能再后續(xù)的實(shí)際開發(fā)中會遇到的BUG:
1. 406:Not Acceptable
2.No converter for [class X] with preset Content-Type 'application/json;charset=UTF-8'].
因?yàn)槌霈F(xiàn)過上面的問題,所以報(bào)錯這些很大可能是我們的lombok注解處理器仍然沒有能正常工作。
測試:我們可以手動的給報(bào)錯所在的類所有字段添加上Getter和Setter方法。
ps: 如果是用IDEA,可以使用快捷鍵【alt + insert】生成。
如果你發(fā)現(xiàn)手動添加上Getter和Setter方法后報(bào)錯消除,說明還是上面所說的問題。
解決
直接在IDEA設(shè)置中把注解處理器的獲取方式設(shè)為"從項(xiàng)目類路徑獲取處理器"。
設(shè)置后,應(yīng)用,lean,重新啟動!
到此這篇關(guān)于IDEA編寫SpringBoot項(xiàng)目時(shí)使用Lombok報(bào)錯“找不到符號”的原因和解決的文章就介紹到這了,更多相關(guān)IDEA Lombok報(bào)錯找不到符號內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決java編譯錯誤( 程序包javax.servlet不存在javax.servlet.*)
這篇文章主要介紹了解決java編譯錯誤的相關(guān)資料,主要解決 程序包javax.servlet不存在javax.servlet.*的問題,需要的朋友可以參考下2017-08-08Java常用鎖synchronized和ReentrantLock的區(qū)別
這篇文章主要介紹了Java常用鎖synchronized和ReentrantLock的區(qū)別,二者的功效都是相同的,但又有很多不同點(diǎn),下面我們就進(jìn)入文章了解具體的相關(guān)內(nèi)容吧。需要的小伙伴也可以參考一下2022-05-05淺析Java如何優(yōu)雅的設(shè)計(jì)接口狀態(tài)碼和異常
HTTP協(xié)議里定義了一系列的狀態(tài)碼用來表明請求的狀態(tài),如常用的200表示請求正常,404表示請求的資源不存在,所以本文就來和大家討論一下如何優(yōu)雅的設(shè)計(jì)接口狀態(tài)碼和異常,感興趣的可以了解下2024-03-03SpringBoot使用Redis實(shí)現(xiàn)分布式緩存
這篇文章主要介紹了SpringBoot redis分布式緩存實(shí)現(xiàn)過程解析,文中通過示例代碼解析的非常詳細(xì),感興趣的同學(xué)可以參考閱讀2023-04-04maven實(shí)現(xiàn)jar包導(dǎo)入+導(dǎo)出方式
這篇文章主要介紹了maven實(shí)現(xiàn)jar包導(dǎo)入+導(dǎo)出方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07Java設(shè)計(jì)模式之裝飾者模式詳解和代碼實(shí)例
這篇文章主要介紹了Java設(shè)計(jì)模式之裝飾者模式詳解和代碼實(shí)例,Decorator模式(別名Wrapper):動態(tài)將職責(zé)附加到對象上,若要擴(kuò)展功能,裝飾者提供了比繼承更具彈性的代替方案,需要的朋友可以參考下2014-09-09IDEA導(dǎo)入jar包的完整實(shí)現(xiàn)步驟
由于導(dǎo)入jar包項(xiàng)目存在很多不確定的問題,導(dǎo)致每次都需要調(diào)試、配置好多遍,對此特意記錄下來,這篇文章主要給大家介紹了關(guān)于IDEA導(dǎo)入jar包的相關(guān)資料,需要的朋友可以參考下2024-01-01