解決mybatis攔截器無法注入spring bean的問題
- 2022 年 2 月 3 日
- 筆記
- JAVA, mybatis, Mybatis攔截器, spring
公司要整合rabbitmq與mybatis攔截器做一個數據同步功能。
整合過程中大部分環節都沒什麼問題,就是遇到了mybatis攔截器
@Intercepts(@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})) @Component public class MyBatisInterceptor implements Interceptor
無法通過註解進行注入一些持久層的dao對象,導致dao一直取到空值。
取dao對象目的是要查詢當前程式碼的執行環境是生產還是測試環境。
因為生產者程式碼不需要在測試環境執行,這個區分的數據存在資料庫裡面。
最初,我通過@Autowired是行不通的,因為
(截取自//segmentfault.com/a/1190000023915286)
所以我繼續尋找方法,於是我找到了用ApplicationContext的方式獲取spring容器企圖劍走偏鋒
結果發現每一次執行ClassPathXmlApplicationContext都會導致容器重新載入,但是我這個MyBatisInterceptor帶了@Component也會跟著重新載入,導致isGrey清空
甚至導致RabbitmqConfig這個類也跟著重新載入
導致這個監聽容易一直重新載入,斷點一直進入,這裡有用到messageListener這個消息監聽器也是一個單例bean對象,也會重新載入
所以會導致測試的時候出現bug,因為這個系統環境資訊sysEnvInfo只需要載入一次
所以ApplicationContext這個方式也是走不通,我不推薦。
思來想去,我發現 mybatis攔截器 具體實現邏輯的方法 produceSqlData 裡面我用的是 SpringBeanUtils.getBean 方法就能獲取得到數據,
RabbitTemplate是定義在RabbitmqConfig程式碼里的,RabbitmqConfig這個類是個@Configuration註解
@Configuration public class RabbitmqConfig
但是獲取的數據是通過@Bean方式獲取的,SpringBeanUtils.getBean無法獲取到sqlSessionFactory
這裡面的dao對象,所以直接
SysEnvInfoDao sysEnvInfoDao = (SysEnvInfoDao)SpringBeanUtils.getBean("sysEnvInfoDao", SysEnvInfoDao.class);
也會報錯,提示sysEnvInfoDao沒有被定義。
所以我思索了下,在@Configuration可以@Autowired成功,那我為何不參考rabbitTemplate一樣把sysEnvInfo也變成一個bean的單例對象呢?
於是我將SysEnvInfo如rabbitTemplate一樣配置成了單例bean對象,通過@Bean註解
在MyBatisInterceptor裡面通過SpringBeanUtils.getBean方式獲取,最後實踐可行,不會出現重複載入容器的問題,也能在攔截器中取到spring bean