Mybatis如何集成到Spring中的

Mybatis如何集成到Spring中的

所谓集成其实说白了就是将mybatis的组件注入到spring容器中,让spring去管理这些组件。下面这段配置我们集成mybatis的时候经常用到:

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- 数据源 -->
    <property name="dataSource" ><ref bean="dataSource" /></property>
    <!-- 别名 -->
    <property name="typeAliasesPackage" value="com.nickyu.learn.mybatis.entity"></property>
    <!-- sql映射文件路径 -->
    <property name="mapperLocations" value="classpath*:com/nickyu/learn/mybatis/mapper/xml/*.xml"></property>
</bean>

<!--4 自动扫描对象关系映射 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!--指定会话工厂,如果当前上下文中只定义了一个则该属性可省去 -->
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
   
</bean>

sqlSessionFactory的作用就是产生一个SqlSessionFactory,而真正将我们写的Mapper接口注入到容器中的就是MapperScannerConfigurer起到的作用,它会根据配置信息(比如配置扫描的包名,注解啥的)扫描所有的Mapper接口,它的实现原理是:
MapperScannerConfigurer本身是一个BeanDefinitionRegistryPostProcessor后置处理器,应用容器在刷新的时候会回调它的postProcessBeanDefinitionRegistry方法:

 ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
scanner.setAddToConfig(this.addToConfig);
scanner.setAnnotationClass(this.annotationClass);
scanner.setMarkerInterface(this.markerInterface);
scanner.setSqlSessionFactory(this.sqlSessionFactory);
scanner.setSqlSessionTemplate(this.sqlSessionTemplate);
scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);
scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);
scanner.setResourceLoader(this.applicationContext);
scanner.setBeanNameGenerator(this.nameGenerator);
scanner.registerFilters();
scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));

从方法体中可以看出,mybatis自定义了一个扫描器ClassPathMapperScanner,这个扫描器主要做了两件事,1、扫描所有的Mapper接口并转换为BeanDefinition 2、对BeanDefinition做修改,比如将它的beanClass改为MapperFactoryBean,设置sqlSessionFactory属性等待。
阅读Mybatis源码可以发现,我们自定义的Mapper接口为什么能在程序中正常使用,是因为Mybatis使用了JDK动态代理技术生成了一个代理对象:

@SuppressWarnings("unchecked")
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}

也就是说spring容器中管理的其实是这些代理对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值