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