Mybatis 源码解析二、Mapper接口的代理实现过程 MapperScannerConfigurer 解析

本文深入探讨Mybatis框架中Mapper接口的代理实现机制,通过分析源码揭示MapperScannerConfigurer如何配置并扫描Mapper接口。了解这一过程对于优化Mybatis使用和自定义开发具有重要意义。
一、使用包扫描的配置方式生成Mapper的动态代理对象
上一篇文章中介绍了SqlSessionFactoryBean 通过Mybatis主配置文件生成Mapper接口的代理对象,并将其保存到 Configuration 中,但是一般在开发中我们并不是采用这种方式配置Mapper接口,因为这种方式是针对单个接口进行配置的,如果有大量的Mapper接口,这样配置就很麻烦。开发中我们通常使用包扫描的方式进行配置。例如下面的配置:
   
   
  1. <!-- mybatis操作接口扫描 -->
  2. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  3. <property name="annotationClass" value="javax.annotation.Resource" />
  4. <property name="basePackage" value="com.xxx.md.xxx.xxx.dao" />
  5. <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
  6. </bean>
   其中basePackage就是我们配置的Mapper文件所在的包,我们追踪下代码来看一下, MapperScannerConfigurer是如何通过包扫描的方式将我们的Mapper保存到Configuration。
1.1 MapperScannerConfigurer 类
    该类的主要作用是初始化我们配置的参数,并调用方法扫描配置的包。
    
   
   
  1. public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
  2. if (this.processPropertyPlaceHolders) {
  3. processPropertyPlaceHolders();
  4. }
  5. ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
  6. scanner.setAddToConfig(this.addToConfig);
  7. scanner.setAnnotationClass(this.annotationClass);
  8. scanner.setMarkerInterface(this.markerInterface);
  9. scanner.setSqlSessionFactory(this.sqlSessionFactory);
  10. scanner.setSqlSessionTemplate(this.sqlSessionTemplate);
  11. scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);
  12. scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);
  13. scanner.setResourceLoader(this.applicationContext);
  14. scanner.setBeanNameGenerator(this.nameGenerator);
  15. scanner.registerFilters();
  16. scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
  17. }
    从上面代码我们可以看到真正执行扫描的是ClassPathMapperScanner类的Scan方法。
   1.2 ClassPathMapperScanner
        ClassPathMapperScanner类继承了Spring提供的ClassPathBeanDefinitionScanner类。Scan方法的实现在父类中。
        
   
   
  1. public int scan(String... basePackages) {
  2. int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
  3. doScan(basePackages);
  4. // Register annotation config processors, if necessary.
  5. if (this.includeAnnotationConfig) {
  6. AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
  7. }
  8. return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
  9. }
        在执行scan()方法时,会执行doScan()方法,这个方法在 ClassPathMapperScanner类中有具体实现。
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值