1. 程式人生 > >springBoot Devtools 與 mybatis 整合後,發現selectByPrimaryKey返回實現類不能順利轉換,報java.lang.ClassCastException異常

springBoot Devtools 與 mybatis 整合後,發現selectByPrimaryKey返回實現類不能順利轉換,報java.lang.ClassCastException異常

1.遇到的問題

@Override
    public User findUserById(Integer userId) throws Exception {
        Object obj = this.userMapper.selectByPrimaryKey(userId);
        System.out.println(obj.getClass().getName());
        System.out.println("selectByPrimaryKey.obj.classLoader:"+obj.getClass().getClassLoader());
        System.out.println("User.class.classLoader:"+User.class.getClassLoader());
        User user = (User) obj;
        return null;
    }

問題就是當我使用tk.mybatis外掛根據userId查詢物件時,查詢回來後資料不能轉換成User。其中user配置與userMapper均為正確

2.分析

那麼為什麼會出現轉換不成功,在這之前我自己也測試通過,但是自新增springboot熱部署外掛Devtools 就出現這個問題,會不會與Devtools 的新增有關了,然後查閱Devtools 相關資訊

這裡貼上devtools原理

devtools:是boot的一個熱部署工具,當我們修改了classpath下的檔案(包括類檔案、屬性檔案、頁面等)時,會重新啟動應用(由於其採用的雙類載入器機制,這個啟動會非常快,如果發現這個啟動比較慢,可以選擇使用jrebel)

  • 雙類載入器機制:boot使用了兩個類載入器來實現重啟(restart)機制:base類載入器(簡稱bc)+restart類載入器(簡稱rc)
    • bc:用於載入不會改變的jar(eg.第三方依賴的jar)
    • rc:用於載入我們正在開發的jar(eg.整個專案裡我們自己編寫的類)。當應用重啟後,原先的rc被丟掉、重新new一個rc來載入這些修改過的東西,而bc卻不需要動一下。這就是devtools重啟速度快的原因。

雙類載入器機制?這不就是用兩個classLoader去載入同一個專案的程式碼嗎?這個機制會不會與 雙親委派模型 嗎?

然後我打印出各自的classLoader發現確實不一樣:

com.sendbp.user.model.User
selectByPrimaryKey.obj.classLoader:[email protected]
User.class.classLoader:org.sprin[email protected]7237dc28

一個是:[email protected]

一個是:org.sprin[email protected]7237dc28

類載入器資料可以參考:

深入理解Java虛擬機器

https://blog.csdn.net/qq_36642340/article/details/81506435

3.解決方法

在使用 DevTools 時,通用Mapper經常會出現 class x.x.A cannot be cast to x.x.A。

同一個類如果使用了不同的類載入器,就會產生這樣的錯誤,所以解決方案就是讓通用Mapper和實體類使用相同的類載入器即可。

DevTools 預設會對 IDE 中引入的所有專案使用 restart 類載入器,對於引入的 jar 包使用 base 類載入器,因此只要保證通用Mapper的jar包使用 restart 類載入器即可。

在 src/main/resources 中建立 META-INF 目錄,在此目錄下新增 spring-devtools.properties 配置,內容如下:

restart.include.mapper=/mapper-[\\w-\\.]+jar
restart.include.pagehelper=/pagehelper-[\\w-\\.]+jar
使用這個配置後,就會使用 restart 類載入載入 include 進去的 jar 包。

可以參考:

https://blog.csdn.net/isea533/article/details/70495714

感興趣的朋友可以關注微信公眾號(會定時推送新的知識):