SpringBoot中MyBatis Mapper的原理核心是动态代理与Spring自动配置。通过@MapperScan或@Mapper注解,Spring启动时扫描接口,利用MapperFactoryBean和JDK动态代理将接口注册为Spring Bean,并由MapperProxy在运行时生成Mapper实例,将方法调用转化为SQL执行。
一、 核心工作原理
-
扫描与定义 (Scanning & Definition) :
- SpringBoot启动时,
@MapperScan注解或MybatisAutoConfiguration会扫描指定包下的Mapper接口。 - 扫描到的接口并不会直接被实例化(因为它是接口),而是将其
BeanDefinition注册到Spring容器中,定义其Bean类型为MapperFactoryBean。
- SpringBoot启动时,
-
动态代理生成 (Dynamic Proxy Generation) :
MapperFactoryBean实现了Spring的FactoryBean接口。当容器需要该Mapper时,getObject()方法被调用。- 使用JDK动态代理 (
Proxy.newProxyInstance),以Mapper接口为代理接口生成一个代理对象。 - 这个代理对象中绑定了
MapperProxy工厂,它会创建实际执行SQL的代理实例。
-
方法调用执行 (Method Execution) :
- 在Service层注入Mapper接口并调用方法(如
userMapper.selectById(1))时,实际执行的是MapperProxy的invoke方法。 MapperProxy会根据方法名找到MyBatis中配置的对应SQL语句(XML或注解)。- 最终通过SqlSession执行SQL、映射结果对象(ResultMap)并返回。
- 在Service层注入Mapper接口并调用方法(如
二、 关键组件
-
@MapperScan / @Mapper: 标识Mapper接口位置,供扫描器识别。
-
MapperFactoryBean: 将Mapper接口转变为Spring Bean的关键中间件。
-
MapperProxyFactory: 产生
MapperProxy实例。 -
MapperProxy: 实现
InvocationHandler,是真正实现SQL映射的逻辑中心。
三、 整合原理图示
Service --> Mapper接口 (Proxy)
|
v
MapperProxy (处理调用,匹配SQL)
|
v
SqlSession --> Executor --> JDBC --> 数据库
四、 @Mapper 与 @MapperScan 的区别
- @Mapper: 需要在每一个Mapper接口上标注,比较繁琐。
- @MapperScan: 在配置类上使用,批量扫描指定包下的所有接口,无需每个接口加注解。