公司要整合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 是行不通的,因為

(截取自 https://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

原文鏈接:https://www.cnblogs.com/longLifeFrog/p/15862067.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/423567.html
標籤:其他
