萍鄉(xiāng)做網(wǎng)站的公司廣州新聞熱點(diǎn)事件
事件背景
同事反饋,相同的jar包,在多人本地的電腦、多臺(tái)服務(wù)器中,都是可以正常啟動(dòng)的,只有在其中一臺(tái)服務(wù)器,簡(jiǎn)稱(chēng)它為A,無(wú)法啟動(dòng),因?yàn)閱?dòng)后的初始化操作中有一個(gè)調(diào)用mybatis方法的操作,
但是調(diào)用該方法后,出現(xiàn) Invalid bound statement (not found): xxxxx
,說(shuō)這個(gè)方法沒(méi)有綁定上的錯(cuò)誤。
調(diào)查
去觀察了一下代碼的配置: mapper-locations: classpath*:com/cm/qrpmp/**/xml/*.xml
好像也并沒(méi)有什么不對(duì)的地方,再加上我自己的電腦本地驗(yàn)證了一下,依然可以正常啟動(dòng),
于是想著遠(yuǎn)程debug一下A服務(wù)器上不行的時(shí)候的堆棧情況,開(kāi)啟遠(yuǎn)程debug模式
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar YourApp.jar
來(lái)到這個(gè)位置后,觀察了一下當(dāng)時(shí)的 configuration 情況,發(fā)現(xiàn)其中的mapper映射確實(shí)沒(méi)有我們想要的,于是觀察了一下當(dāng)時(shí)的mapper方法掃描的數(shù)量,大概是1145個(gè),
隨后我們?cè)诒镜匾矄?dòng)了調(diào)試,在這個(gè)位置,發(fā)現(xiàn)掃描出來(lái)的mapper方法是1445個(gè),多了300個(gè),也就是說(shuō)服務(wù)器上并沒(méi)有掃描到和本地一樣的方法數(shù)量,奇怪的是其他服務(wù)器是可以的,
這個(gè)過(guò)程中我們檢查了打包后的配置文件、以及xml文件有沒(méi)有被打包進(jìn)去,發(fā)現(xiàn)都是正確的,
繼續(xù)追蹤
于是想看一下mybatis plus在掃描我們指定的路徑過(guò)程中發(fā)生了什么,
這里追蹤到了MyBatisSqlSessionFactoryBean的buildSqlSessionFactory方法這里,在這里發(fā)現(xiàn) mapperLocations 是一個(gè)空的對(duì)象,說(shuō)明這里并沒(méi)有被注入,
于是再向上追蹤一下這個(gè)對(duì)象從什么地方注入的,發(fā)現(xiàn)他在 MybatisPlusAutoConfiguration中的 sqlSessionFactory 方法這里進(jìn)行注入,
其來(lái)源自 MybatisPlusProperties 中的 resolveMapperLocations 方法,
于是再這里打了斷點(diǎn)調(diào)試后,真相即將出現(xiàn)了,在A這臺(tái)服務(wù)器上這里出現(xiàn)的路徑竟然不是我們配置中寫(xiě)的,而是另一個(gè)毫不相干的,
所以問(wèn)題出現(xiàn)了在哪里?因?yàn)檫@個(gè)錯(cuò)誤的配置是另一個(gè)jar中的,一度懷疑是不是云服務(wù)器出現(xiàn)了緩存啥的讀取信息錯(cuò)誤。。。
于是換個(gè)路徑啟動(dòng),發(fā)現(xiàn)正常了。。。。 回到原本的路徑就不行,再細(xì)看這個(gè)路徑下有一個(gè)config目錄。。。。 config目錄里有spring boot的 yaml 配置文件,而這個(gè)配置文件中的路徑就是剛剛debug出錯(cuò)誤的路徑。。。。
把這個(gè)文件刪除后,啟動(dòng)又正常了。。。 所以瞬間懷疑,spring boot 默認(rèn)讀取了這個(gè)文件中的配置?
解決
在本地驗(yàn)證了一下發(fā)現(xiàn)確實(shí)如此,如果jar的同目錄中存在一個(gè)config目錄,里面有yaml文件的話(huà) spring boot默認(rèn)會(huì)讀這個(gè),所以出現(xiàn)了這個(gè)烏龍,
spring boot的讀取順序:https://blog.csdn.net/qq_52139871/article/details/124872875
所以最終其實(shí)是spring boot對(duì)yaml文件讀取順序?qū)е碌膯?wèn)題,我們一直以為它會(huì)讀jar包中的,沒(méi)想到這個(gè)config目錄 近水樓臺(tái)先得月了。
PS(其他服務(wù)器可以,是因?yàn)樗谄渌?wù)器啟動(dòng)的時(shí)候又手動(dòng)指定了spring.config.location,A這臺(tái)直接用了java -jar 沒(méi)指定,所以默認(rèn)讀了當(dāng)前的config下。。。)總之,各方面的原因?qū)е铝藛?wèn)題的出現(xiàn),這里又驗(yàn)證了多了解源碼實(shí)現(xiàn)也是有好處的,掌控你所使用的東西