進入convenient項目後遇到了枚舉類處理器不能正確被處理的問題,經過查找,找到了相關的代碼
可以看見通過配置mybatis的數據庫會話工廠類,我們能夠對枚舉處理器進行配置。
但是爲什麼這個處理器沒有生效呢?
經過我兩天對着源碼一行一行的排查,發現這樣一個問題:
這個getObject()方法是一個單例方法,在return行的再次調用並沒有讓它再次執行配置方法。
而另一邊,mybatis的類型轉換註冊器就像它的名字一樣,執行的是一個註冊策略,拿到一個類型的字段後,mybatis會根據這個字段的類型去註冊表中找到相應的處理器,而註冊的方法名就是register(......)。
在這個機制的基礎上,我們發現sqlSessionFactory被build的過程中,默認類型轉換處理器已經被註冊完畢了(具體是在MybatisSqlSessionFactoryBean的615行的xmlMapperBuilder的parse方法中)
所以,圖中的setDefaultEnumTypeHandler()方法只是替換了一個已經被用完了的默認類型處理器而已,並沒有被註冊,自然也派不上用場了。
知道了錯誤原因,那修正就很簡單了,只需要將配置提前到單例類生成就行了。
在這次修正中有兩點值得注意:
一點就是除了默認的類型處理器外,另外的兩個處理器都是有效的,因爲它們都是使用了註冊方法註冊進了註冊表裏面;
第二點就是爲什麼老一套(就是sqlProvider那一套)能夠正常解析枚舉類呢?
我也思考了很久,以爲是走了什麼特殊的方法,但始終沒有找到,當我嘗試着把配置文件回滾了,然後老一套也開始報錯了,因爲無法復現所以目前也沒有什麼頭緒。
以下內容爲個人的一點猜測:
register方法不僅僅在被初始化的時候用到了,所以呢,也沒準mybatis遇到了一個沒處理過的新類型的時候,會拿默認的類型處理器現註冊一個,這個過程在初始化之後,所以能夠用上我們自定義的處理器……現在也沒法考證了……