最近在做的一个项目因为需要用到JDK1.8的一些组件所以需要对旧项目升级并转化为springboot的web项目分为以下几个步骤
1. maven依赖升级
对于大部分业务代码service和dao层spring是可以做到无缝兼容的,直接升级对面的依赖版本的就可以了
2. xml文件中bean的问题
在spring boot出现之前java web开发一般都是在webapp/WEB-INF下配置一个xml文件在里面定义各种bean和bean的依赖关系,如数据库连接配置信息,数据库连接池bean,mybatis的SqlSessionFactory等bean的依赖关系.
如何轻松复用xml文件中定义的bean呢?很简单
(1)xml文件放在resource目录下
(2)在springboot启动的类上添加注解@ImportResource({“classpath:XMLBeans.xml”"}),就可以轻松将xml中的bean托管到spring中
(3)检查各个配置项是否正确,项目能正常启动运行,如果成功启动,试试你的接口应该就能正常调用了,恭喜
但是还是一个问题没有解决,而且很难发现,只会在运行时期暴露出来,对于部分mybatis查询会报
Parameter '×××' not found. Available parameters are [0, 1, param1, param2]
这个异常信息
3. mybatis高版本的兼容性问题
对于低版本的mybatis中极有可能存在通过#{0} #{1}的方式取参数,在spring boot支持的mybatis版本中
是不推荐,也不支持这种写法的,所以就给我们的迁移工作带来了巨大的困难,笔者经过分析源码得到关键点在(3.4.6t版本)的类org.apache.ibatis.reflection.ParamNameResolver#ParamNameResolver
的第74行关键代码
// @Param was not specified.
//74 if (config.isUseActualParamName()) {
name = getActualParamName(method, paramIndex);
}
原来只需要把configuration的useActualParamName配置成false就支持#{0} #{1}取参数了
于是信心满满的在主配置文件中配置了mybatis.configuration.use-actual-param-name=false
但是一运行发现还是依旧报错,很奇怪.于是追踪了org.apache.ibatis.session.Configuration的构造过程
发现springboot在启动也确实将构造的Configuration的useActualParamName设置成了false,但是在
调用时上文中74行依旧是true为什么还是不生效呢?然后笔者又追踪了mybati接口调用过程中的org.apache.ibatis.binding.MapperProxy,发现其中的configuration对象和之前那个configuration对象的
hashCode居然不一致,我恍然大悟原来是因为xml中的configuration对象的useActualParamName依旧是
true,所以解决的方式就是在xml中配置上bean
编译,运行,调用ok,完美升级旧的项目,不改业务代码完成迁移
后记
在带个追踪过程中,网上可参考的资料也没什么太大价值,主要还是通过debug源码来分析追踪,所以对
源码体系的掌握对解决一些其他人没有遇到过的问题是很有帮助了,如果不阅读源码这个问题是没办法找到解决的方案的