MyBatis的默认对象工厂org.apache.ibatis.reflection.factory.ObjectFactory

objectFactory.create(resultType) 的实现在MyBatis的默认对象工厂中。让我带你找到具体的源码位置:

1. 接口定义

首先在 org.apache.ibatis.reflection.factory.ObjectFactory 接口中:

java 复制代码
public interface ObjectFactory {
  /**
   * 使用默认构造函数创建对象
   */
  <T> T create(Class<T> type);
  
  // 其他重载方法...
}

2. 默认实现

org.apache.ibatis.reflection.factory.DefaultObjectFactory 中:

java 复制代码
public class DefaultObjectFactory implements ObjectFactory, Serializable {

  @Override
  public <T> T create(Class<T> type) {
    return create(type, null, null);
  }

  @Override
  public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
    // 1. 解析实际要实例化的类(处理集合接口)
    Class<?> classToCreate = resolveInterface(type);
    
    // 2. 调用具体创建方法
    return (T) instantiateClass(classToCreate, constructorArgTypes, constructorArgs);
  }

  private <T> T instantiateClass(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
    try {
      Constructor<T> constructor;
      
      // 3. 如果没有构造函数参数,使用默认构造函数
      if (constructorArgTypes == null || constructorArgs == null) {
        constructor = type.getDeclaredConstructor();
        try {
          // 4. 调用无参构造函数创建实例
          return constructor.newInstance();
        } catch (IllegalAccessException e) {
          // 如果访问受限,设置可访问后重试
          if (Reflector.canControlMemberAccessible()) {
            constructor.setAccessible(true);
            return constructor.newInstance();
          } else {
            throw e;
          }
        }
      }
      
      // 5. 如果有构造函数参数,使用有参构造函数(这是你出错的分支)
      constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[0]));
      // ... 有参构造逻辑
      
    } catch (Exception e) {
      // 异常处理
    }
  }
}

3. 关键源码路径

完整的调用栈是:

复制代码
org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject()
↓
org.apache.ibatis.reflection.factory.ObjectFactory.create(Class<T> type)
↓
org.apache.ibatis.reflection.factory.DefaultObjectFactory.create(Class<T> type)
↓
org.apache.ibatis.reflection.factory.DefaultObjectFactory.instantiateClass()
↓
java.lang.reflect.Constructor.newInstance()  // 最终调用Java反射API

4. 在你的错误堆栈中的体现

回顾你的错误堆栈:

复制代码
Caused by: org.apache.ibatis.reflection.ReflectionException: 
Error instantiating class cn.wh.dueremind.entity.ExcelImportRecord 
with invalid types (Long,String,String,String,ObjectNode,ObjectNode,ObjectNode,...)

at org.apache.ibatis.reflection.factory.DefaultObjectFactory.instantiateClass(DefaultObjectFactory.java:86)
at org.apache.ibatis.reflection.factory.DefaultObjectFactory.create(DefaultObjectFactory.java:53)

这正好对应:

  • 第86行:DefaultObjectFactory.instantiateClass() 中的有参构造调用
  • 第53行:DefaultObjectFactory.create() 方法

5. 实际执行流程

当你的类有无参构造函数时:

java 复制代码
// MyBatis执行路径:
objectFactory.create(ExcelImportRecord.class)
↓
instantiateClass(ExcelImportRecord.class, null, null)  // 参数为null
↓
constructor = ExcelImportRecord.class.getDeclaredConstructor()  // 获取无参构造
↓
return constructor.newInstance()  // 成功创建实例!

当你的类没有无参构造函数时:

java 复制代码
// MyBatis执行路径:
objectFactory.create(ExcelImportRecord.class)
↓
instantiateClass(ExcelImportRecord.class, constructorArgTypes, constructorArgs)  // 有参数!
↓
// 尝试匹配有参构造函数,但ObjectNode类型不匹配
↓
失败!抛出 ReflectionException

6. 自定义ObjectFactory

你也可以实现自定义的ObjectFactory:

java 复制代码
public class CustomObjectFactory extends DefaultObjectFactory {
  @Override
  public <T> T create(Class<T> type) {
    // 自定义创建逻辑
    if (type == ExcelImportRecord.class) {
      return (T) new ExcelImportRecord();
    }
    return super.create(type);
  }
}

然后在配置中指定:

xml 复制代码
<settings>
  <objectFactory type="com.example.CustomObjectFactory"/>
</settings>

总结

objectFactory.create(resultType) 的核心实现在:

  • 接口org.apache.ibatis.reflection.factory.ObjectFactory
  • 默认实现org.apache.ibatis.reflection.factory.DefaultObjectFactory
  • 关键方法instantiateClass() 中的无参构造调用

这就是MyBatis创建实体类实例的最终执行者!

相关推荐
武子康2 小时前
大数据-150 Apache Druid 单机部署实战:架构速览、启动清单与故障速修
大数据·后端·apache
java1234_小锋3 小时前
MyBatis如何处理懒加载和预加载?
java·开发语言·mybatis
星光一影5 小时前
SpringBoot+Vue3无人机AI巡检系统
人工智能·spring boot·websocket·mysql·intellij-idea·mybatis·无人机
小马爱打代码15 小时前
MyBatis:性能优化实战 - 从 SQL 优化到索引设计
sql·性能优化·mybatis
SelectDB15 小时前
Apache Doris 4.0.1 版本正式发布
数据库·apache
烤麻辣烫18 小时前
黑马程序员苍穹外卖(新手)Day1
java·数据库·spring boot·学习·mybatis
qiudaorendao19 小时前
作业11.9
linux·服务器·apache
SelectDB21 小时前
冷查第一,再登榜首!Apache Doris 3.1 全面刷新 JSONBench 性能纪录
数据库·apache
IT小哥哥呀1 天前
MyBatis 性能优化指南:Mapper 映射、缓存与批量操作实战
缓存·性能优化·mybatis·数据库优化·批量插入·分布式系统·sql性能