首先看下我們spring和mybatis掃描包的時候是怎樣寫:
有兩種寫法:
第一種寫法:
<mybatis-spring:scan base-package="com.gupaoedu.crud.dao"/>
第二種寫法:
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.gupaoedu.crud.dao"/> </bean>
第一種寫法是spring解析xml文件時提供了一個鈎子方法給其他框架去解析他們自定義的標簽


1.那為什么要去解析mybatis的NameSpaceHander呢他又沒注入到容器里?
2.圖中時scan而不是mybatis-spring:scan
問題解析:
首先配置applcationcContext.xml時


會加入這個文件,如果不加入的話就會xml的約束會提示mybatis-spring:scan報錯的
spring啟動的時候會查找META-INF/spring.handlers 這個文件下的內容,下圖所示




這里就關聯上了,spring會掃描這個文件下的內容
因此這下面三個東西就關聯上了。<mybatis-spring:scan > 標簽找到 http\://mybatis.org/schema/mybatis-spring 再找到org.mybatis.spring.config.NamespaceHandler
這樣就可以解析自定義標簽了
http\://mybatis.org/schema/mybatis-spring org.mybatis.spring.config.NamespaceHandler mybatis-spring
下面這一點就是注入相應的解析器代碼


現在分析spring+mybatis結合的入口分析
寫法一入口查看:


寫一部查看一下解析器里面的內容


寫法二也是通過ClassPathMapperScanner掃描包的,所以這里也一同分析方法二
因為掃描的操作是一樣的,后面再分析是怎么掃描的:
寫法二是注入MapperScannerConfigurer: 打開查看


因為實現了BeanDefinitionRegistryPostProcessor 所以注入BeanDefinition后會調用postProcessBeanDefinitionRegistry


從上圖所示也是和寫法一一樣通過ClassPathMapperScanner 來掃描包

查看ClassPathMapperScanner的繼承的類

我們查看一下ClassPathMapperScanner.scan方法 他是他父類的方法來的


然后再查看doScan 這個ClassPathMapperScanner 重寫了父類的方法:


現在查看一下this.processBeanDefinitions(beanDefinitions);


幫接口都注入了實現類mapperFactoryBean,
mapperFactoryBean如下


mapperFactoryBean構造方法是要帶上類名的。。因為實現了FactoryBean 從容器取出對象時會調用getObject。從getOject里可以看到
this.getSqlSession().getMapper(this.mapperInterface);
這就是mybatis操作數據庫的操作了。。所以文章也到此結束了