mybatis的接口Mapper注入生成代理的流程
2024-07-12 11:09:15 0 举报
AI智能生成
mybatis的接口Mapper注入生成代理的流程
作者其他创作
大纲/内容
MapperScannerRegistrar实现ImportBeanDefinitionRegistrar#registerBeanDefinitions
如何在代码中生效
1
在spring生命周期中的invokeBeanFactoryPostProcessor里面的ConfigrationClassPostProcessor扫描MapperScan的的注解Import来实现
解析@MapperScan注解
<div><span style="font-size: inherit;">扫描BeanDefinition</span><br></div>调用ClassPathMapperScanner#doScan,扫描得到指定路径下的所有BeanDefinition<br>
修改BeanDefinition,篡改实例Bean<br>遍历所有扫描的BeanDefinition,设置BeanClass为MapperFactoryBean,<br>以及设置属性SqlSessionTemplate等,同时:<br>definition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName);因为MapperFactoryBean的构造函数就是对应的接口的Class<?>,<br>
如果构造参数是字符串类型(即 Mapper 接口的全路径名),Spring 会尝试将其转换为 Class 类型。这是通过 TypeConverter 完成的,TypeConverter 是 Spring 用于在 Bean 属性和构造参数之间进行类型转换的工具。
SqlSession实现线程事务共享:SqlSessionTemplate实现了SqlSession接口,里面引用了sqlSession,然后这个类被代理了,而SqlSession采用InvocationHandler为SqlSessionInterceptor进行拦截代理,目的是为了采用ThreadLocal实现了SqlSession在线程事务共享<br>(SqlSessionHolder) TransactionSynchronizationManager.getResource(sessionFactory)<br>
MapperScannerConfigurer:<br>MapperScannerConfigurer实现BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
如何在代码中生效
<br>
AutoConfiguredMapperScannerRegistrar注入MapperScannerConfigurer,并且指定扫描类型的注解为@Mapper
spring生命周期中执行postProcessBeanDefinitionRegistry refresh()里面的invokeBeanFactoryPostProcessor()
扫描指定类型注解的@Mapper<br>调用ClassPathMapperScanner#doScan
修改BeanDefinition,篡改实例Bean<br>遍历所有扫描的BeanDefinition,设置BeanClass为MapperFactoryBean,<br>以及设置属性SqlSessionTemplate等,同时:<br>definition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName);因为MapperFactoryBean的构造函数就是对应的接口的Class<?>,而MapperFactoryBean得getClass获取得就是构造函数传来得Class<br>
如果构造参数是字符串类型(即 Mapper 接口的全路径名),Spring 会尝试将其转换为 Class 类型。这是通过 TypeConverter 完成的,TypeConverter 是 Spring 用于在 Bean 属性和构造参数之间进行类型转换的工具。
SqlSession实现线程事务共享:SqlSessionTemplate实现了SqlSession接口,里面引用了sqlSession,然后这个类被代理了,而SqlSession采用InvocationHandler为SqlSessionInterceptor进行拦截代理,目的是为了采用ThreadLocal实现了SqlSession在线程事务共享<br>(SqlSessionHolder) TransactionSynchronizationManager.getResource(sessionFactory)<br>
MapperFactoryBean
getObject()->getSqlSession()
getSqlSession()->getMapper(),其中这里得SqlSession是SqlSessionTemplate
mapperRegistry.getMapper->mapperProxyFactory.newInstance(sqlSession)->MapperProxy#invoke->MapperMethod#execute
ChannelMapper代理类效果如下:<br>为什么是MybatisMapperProxy,而不是MapperProxy?<br>因为我们用的是Mybatisplus框架而不是Mybatis框架,苞米豆对这些类都复制重写了,同时扩展了自己的新的功能
注意了没,代理对象里面有一个h的属性是(InvocationHandler实例),这个实例实际上并不是原始对象本身,<br>而是一个处理调用的方法。通过这个 InvocationHandler,代理对象可以拦截对代理方法的调用,并将其转发到真正的实现逻辑
这个对象生产的过程当然不包含调用,我们也要一提:我们在调用接口的时候,其实最终调用的都是MapperProxy#invoke->MapperMethod#execute,,如何后面执行,请点击链接<br>
0 条评论
下一页