mybatis执行流程分析

mybatis执行流程分析


后端

配置加载

通过 XMLConfigBuilder.parse 解析configuration.xmlmapper.xml 生成org.apache.ibatis.session.Configuration,生成 SqlSessionFactory

public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
SqlSessionFactory var5;
try {
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
var5 = this.build(parser.parse());
} catch (Exception var14) {
throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException var13) {
}
}
return var5;
}
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}

在生成Configuration 的过程,通过XMLMapperBuilder.parse -> XMLStatementBuilder.parseStatementNode -> XMLLanguageDriver.createSqlSource -> XMLScriptBuilder.parseDynamicTags -> Configuration.addMappedStatement 解析sql语句标签,生成对应的MappedStatement 对象,以id 作为key 放在 Configuration 的mappedStatements的map 中。

mapper对象的注册

MapperScan 注解引入了 MapperScannerRegistrar 的bean

image-20211110152624776

MapperScannerRegistrar 实现了接口 ImportBeanDefinitionRegistrar.registerBeanDefinitions ,注册了MapperScannerConfigurer 的bean

public class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
public MapperScannerRegistrar() {
}
/** @deprecated */
@Deprecated
public void setResourceLoader(ResourceLoader resourceLoader) {
}
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//处理注解 MapperScan
AnnotationAttributes mapperScanAttrs = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));
if (mapperScanAttrs != null) {
this.registerBeanDefinitions(mapperScanAttrs, registry, generateBaseBeanName(importingClassMetadata, 0));
}
}
void registerBeanDefinitions(AnnotationAttributes annoAttrs, BeanDefinitionRegistry registry, String beanName) {
//添加 MapperScannerConfigurer 的bean定义
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class);
List<String> basePackages = new ArrayList();
basePackages.addAll((Collection)Arrays.stream(annoAttrs.getStringArray("value")).filter(StringUtils::hasText).collect(Collectors.toList()));
basePackages.addAll((Collection)Arrays.stream(annoAttrs.getStringArray("basePackages")).filter(StringUtils::hasText).collect(Collectors.toList()));
basePackages.addAll((Collection)Arrays.stream(annoAttrs.getClassArray("basePackageClasses")).map(ClassUtils::getPackageName).collect(Collectors.toList()));
String lazyInitialization = annoAttrs.getString("lazyInitialization");
if (StringUtils.hasText(lazyInitialization)) {
builder.addPropertyValue("lazyInitialization", lazyInitialization);
}
builder.addPropertyValue("basePackage", StringUtils.collectionToCommaDelimitedString(basePackages));
registry.registerBeanDefinition(beanName, builder.getBeanDefinition());
}
}

image-20211110154806612

MapperScannerConfigurer 实现了 BeanDefinitionRegistryPostProcessor 接口,扫描mapper 包

public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware {
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ",; \t\n"));
}
}

ClassPathMapperScanner 覆盖了 ClassPathBeanDefinitionScannerdoScan 方法,扫描mapper接口并配置其生成bean的工厂bean

public class ClassPathMapperScanner extends ClassPathBeanDefinitionScanner {
private Class<? extends MapperFactoryBean> mapperFactoryBeanClass = MapperFactoryBean.class;
public Set<BeanDefinitionHolder> doScan(String... basePackages) {
//父类逻辑
Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
//自己的逻辑
this.processBeanDefinitions(beanDefinitions);
return beanDefinitions;
}
private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) {
GenericBeanDefinition definition;
for(Iterator var3 = beanDefinitions.iterator(); var3.hasNext(); definition.setLazyInit(this.lazyInitialization)) {
BeanDefinitionHolder holder = (BeanDefinitionHolder)var3.next();
definition = (GenericBeanDefinition)holder.getBeanDefinition();
//mapper 接口类型
String beanClassName = definition.getBeanClassName();
//MapperFactoryBean 构造器的参数为 mapper 接口类型
definition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName);
//org.mybatis.spring.mapper.MapperFactoryBean
definition.setBeanClass(this.mapperFactoryBeanClass);
boolean explicitFactoryUsed = false;
//MapperScan中指定了SqlSessionTemplate,则explicitFactoryUsed = true
...
//如果没指定SqlSessionTemplate,则按类型注入SqlSessionTemplate
if (!explicitFactoryUsed) {
LOGGER.debug(() -> "Enabling autowire by type for MapperFactoryBean with name '" + holder.getBeanName() + "'.");
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
}
}
}
}

image-20211111170030530

public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> {
private Class<T> mapperInterface;
private boolean addToConfig = true;
public MapperFactoryBean() {
}
protected void checkDaoConfig() {
super.checkDaoConfig();
Configuration configuration = this.getSqlSession().getConfiguration();
if (this.addToConfig && !configuration.hasMapper(this.mapperInterface)) {
//添加mapper 代理工厂
configuration.addMapper(this.mapperInterface);
}
}
//通过此方法实例工厂bean,传入要生成代理对象的接口
public MapperFactoryBean(Class<T> mapperInterface) {
this.mapperInterface = mapperInterface;
}
//通过sqlSession获取代理对象
public T getObject() throws Exception {
return this.getSqlSession().getMapper(this.mapperInterface);
}
public Class<T> getObjectType() {
return this.mapperInterface;
}
public boolean isSingleton() {
return true;
}
}

image-20211110164204151

checkDaoConfig 方法会在bean初始化后在afterPropertiesSet 里被调用,实际上是调用 MapperRegistry.addMapper ,添加代理工厂MapperProxyFactory

public <T> void addMapper(Class<T> type) {
this.knownMappers.put(type, new MapperProxyFactory(type));
}

MapperFactoryBean.getObject 调用 MapperRegistry.getMapper ,最后通过 MapperProxyFactory 创建MapperProxy

public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
return mapperProxyFactory.newInstance(sqlSession);
}

Mapper 接口的代理对象 MapperProxy ,通过 MapperMethod 调用 SqlSessionTemplate -> SqlSessionInterceptor -> sqlSession执行sql

public class MapperProxy<T> implements InvocationHandler, Serializable {
private final SqlSession sqlSession;
private final Class<T> mapperInterface;
private final Map<Method, MapperMethod> methodCache;
public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethod> methodCache) {
this.sqlSession = sqlSession;
this.mapperInterface = mapperInterface;
this.methodCache = methodCache;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MapperMethod mapperMethod = this.cachedMapperMethod(method);
return mapperMethod.execute(this.sqlSession, args);
}
private MapperMethod cachedMapperMethod(Method method) {
return (MapperMethod)this.methodCache.computeIfAbsent(method, (k) -> {
return new MapperMethod(this.mapperInterface, method, this.sqlSession.getConfiguration());
});
}
}
public class SqlSessionTemplate implements SqlSession, DisposableBean {
private class SqlSessionInterceptor implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//如果有事务,则从事务管理器中获取SqlSession,否则由sqlSessionFactory开启新的SqlSession
SqlSession sqlSession = getSqlSession(SqlSessionTemplate.this.sqlSessionFactory,
SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);
try {
//调用sqlSession对应方法
Object result = method.invoke(sqlSession, args);
if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
//没有配置事务,则立即提交当前sql操作,否则由事务管理器处理事务
sqlSession.commit(true);
}
return result;
} catch (Throwable t) {
} finally {
if (sqlSession != null) {
//没有事务则立即关闭
closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
}
}
}
}
}

image-20211111165335234

Sql 执行

public class DefaultSqlSession implements SqlSession {
@Override
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
try {
//根据key从configuration中获取sql语句配置对象
MappedStatement ms = configuration.getMappedStatement(statement);
return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
}

image-20211112190831641

public class CachingExecutor implements Executor {
@Override
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
//替换${...}的变量 ,#{...} 解析成jdbc的语句参数,用问号占位
BoundSql boundSql = ms.getBoundSql(parameterObject);
CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
}

image-20211112190917737

public class SimpleExecutor extends BaseExecutor {
@Override
public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
Statement stmt = null;
try {
Configuration configuration = ms.getConfiguration();
//handler 中包含了ParameterHandler,ResultSetHandler
StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
//获取数据库连接,返回jdbc的Statement,ParameterHandler 设置jdbc的sql参数
stmt = prepareStatement(handler, ms.getStatementLog());
//发送sql到数据库执行,ResultSetHandler解析sql结果转换成实体对象返回
return handler.<E>query(stmt, resultHandler);
} finally {
closeStatement(stmt);
}
}
}

image-20211112191256092

public class PreparedStatementHandler extends BaseStatementHandler {
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
//发送到数据库执行sql
ps.execute();
//解析返回结果
return resultSetHandler.<E> handleResultSets(ps);
}
}

image-20211112191323057