一般我们这样配置
内部使用 ClassPathMapperScanner 来扫描包下面的mapper接口,每个接口构建一个BeanDefinitionHolder(beanclass为MapperFactoryBean)
当需要mapperinterface实例时,由MapperFactoryBean工厂产生
public T getObject() throws Exception { return this.getSqlSession().getMapper(this.mapperInterface); }
可以吧this.getSqlSession()看做是sqlSessionFactory的封装SqlSessionTemplate,实际调用
publicT getMapper(Class 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 详细过程见 ,parse中xml的namespace相应的class注册给configuration
publicvoid addMapper(Class 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);
进一步的调用过程见
如何在调用中事务起作用,见下篇