MyBatis-09-FactoryBean的问题

ListableBeanFactory#getBeanNamesForType(Class<?>)

这个方法的逻辑在对 FactoryBean 进行判断时,会使用 FactoryBean 的生成的对象的类型进行判断

  1. BD 的属性数据 AttributeAccessor.getAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE)
  2. 反射创建对象并调用 FactoryBean#getObjectType
  3. 实例化 Bean 并调用 FactoryBean#getObjectType

那么对于 MyBatis 这种,直接实例化 MapperFactoryBean 的 getObjectType 是不会返回确定的类型的,只有1和3会返回,如果在创建 BeanDefinition
时没有 setAttribute,那么就会发生提前实例化的问题

问题又在与这个提前实例化失败时 Spring 不会抛出异常停止应用的启动,而是将底层的异常捕获并打印 debug 日志

切实遇到的问题

公司在 MyBatis-Spring 的基础上自己进行了 SpringBoot 风格的适配,但是在创建 BeanDefinition 时没有 setAttribute,导致如果
XML的Mapper啊这些写得有问题,那么 MapperFactoryBean 在实例化时会依赖相关的 MyBatis 的 Bean 的构建,当构建失败,不会停止应用。

于是产生的问题是

  1. Dao/Mapper 都生成了对应的 MapperFactoryBean
  2. getBeanNamesForType 在没有找到时会遍历它们判断
  3. 实例化对应的 MapperFactoryBean -> 扫描 XML 文件 -> 解析报错 -> 抑制异常
  4. 重复 3 直到处理完毕

于是就造成了一旦 XML 写错,控制台就会打印大量日志,给人感觉像是一直死循环处理一样的

解决方案

实际上 Spring 和 MyBatis 在后续版本已经解决了这个这个问题,就是 setAttribute,但是公司的版本没有继续迭代

posted @ 2024-04-16 22:46  YangDanMua  阅读(7)  评论(0编辑  收藏  举报