最近遇到之前公司同事的求助信息
图文如下
接着我让他把他项目里面的拦截器代码截图过来。
这个项目当时我参与的时候分库是采用mycat,配合Filter+修改mysql驱动包来实现分库路由。最近他们项目升级,采用新框架重构,然后也换了方式来实现。新版本的项目采用mybatis的拦截器实现。我第一直觉问题可能是拦截错了对象,关于mybatis拦截的拦截对象有Executor、ParameterHandler、StatementHandler、ResultSetHandler四个对象里面的方法。至于里面的区别我不细谈,我推荐他使用最底层的对象Executor。Executor是mybatis的核心接口,所有mapper的执行最终都是通过Executor执行器来操作的。结果并没有解决问题。。。。。
mybatis拦截器依然没有将路由标识拼接进去,而他们项目里面自己编写的sql是可以拼接上路由标识。
那我觉得问题可能不太简单,需要关注下他们项目目前使用的activiti工具包。首先确定是不是采用mybatis。由于我本地拉不下来跟他同版本的activiti-engine包,只能让他把jar发我反编译看下,结合他项目配置类配置定位到ProcessEngineConfigurationImpl这个关键类,顾名思义流程引擎配置类。
构建流程引擎对象中有init()初始化方法
只需关注init()方法中关于sqlsessionFactory的初始化操作。
通过代码分析发现,在构建sqlSessionFactory中activiti确实使用了mybatis中的DefaultSqlSessionFactory来初始化sqlSessionFactory对象。那么为什么拦截不到,这就很奇怪了。于是我想到去找mybatis的源码看看拦截器的注入时机。
首先Mybatis中关于sqlsessionFactory的定义 已经能初现端倪。
Configuration的定义是关联到sqlsessionFactory,而Configuration中拦截器注入的是拦截器责任链对象
说明拦截器是绑定到sqlsessionFactory中,至于工作流中的sql拦截不到,上面ProcessEngineConfigurationImpl这个类中自己构造了sqlsessionFactory对象,此对象的Configuration并不会自动注入业务自己实现的拦截器。所以问题的关键是要在合适的时机注入业务自己实现的拦截器。经过几次尝试代码如下
启动项目测试 发现自定义的 mybatis拦截器正常工作,并能够在工作流sql拦截拼上mycat分库路由标识,至此大功告成。由此问题得到解决,小伙伴们记得在遇到多sqlsessioFactory的时候,拦截器失效,可以尝试下楼主的方案~