一般我們這樣配置
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
lazy-init="false">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:sqlmapper/*Mapper.xml"/>
<property name="plugins">
<list>
<bean class="***">
<property name="dialect">
<bean class="***"/>
</property>
</bean>
</list>
</property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="*.*.*" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> </bean>
內部使用 ClassPathMapperScanner 來掃描包下面的mapper接口,每個接口構建一個BeanDefinitionHolder(beanclass為MapperFactoryBean)
當需要mapperinterface實例時,由MapperFactoryBean工廠產生
public T getObject() throws Exception { return this.getSqlSession().getMapper(this.mapperInterface); }
可以吧this.getSqlSession()看做是sqlSessionFactory的封裝SqlSessionTemplate,實際調用
public <T> T getMapper(Class<T> type) {
return this.getConfiguration().getMapper(type, this);
}
這里的this.getConfiguration()實際是
return this.sqlSessionFactory.getConfiguration();
走到這步,就必須來看SqlSessionFactoryBean做了什么吧?關鍵方法如下:
protected SqlSessionFactory buildSqlSessionFactory() throws IOException { XMLConfigBuilder xmlConfigBuilder = null; Configuration configuration; .................. if(this.transactionFactory == null) { this.transactionFactory = new SpringManagedTransactionFactory(); } Environment var29 = new Environment(this.environment, this.transactionFactory, this.dataSource); configuration.setEnvironment(var29); ............... if(!ObjectUtils.isEmpty(this.mapperLocations)) { XMLMapperBuilder e = new XMLMapperBuilder(var33.getInputStream(), configuration, var33.toString(), configuration.getSqlFragments()); e.parse(); } return this.sqlSessionFactoryBuilder.build(configuration); }
紅色部分,設置configuration->environment->springManagedTransactionFactory
XMLMapperBuilder 詳細過程見 mybatis緩存創建過程 ,parse中xml的namespace相應的class注冊給configuration
public <T> void addMapper(Class<T> type) {
this.mapperRegistry.addMapper(type);
}
最后的return調用 SqlSessionFactoryBuilder
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
這里的Configuration對象很關鍵
總結如下:org.mybatis.spring.SqlSessionFactoryBean解析mapper xml配置,根據namespace添加class mapper組裝Configuration對象,包裝為DefaultSqlSessionFactory;
org.mybatis.spring.mapper.MapperScannerConfigurer掃描basePackage下的mapper接口,封裝為MapperFactoryBean注冊給spring容器,當調用"mapper接口"時去DefaultSqlSessionFactory-》Configuration獲得接口類的代理類
MapperProxy mapperProxy = new MapperProxy(sqlSession, this.mapperInterface, this.methodCache);
進一步的調用過程見 mybatis緩存
如何在調用中事務起作用,見下篇