源码分析----Mybatis
一、源码分析
1、创建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
·1.1 调用了parse方法,将mybatis配置文件的信息全部解析到一个Configuration对象中(包扩mybatis启动配置信息,数据源,Mapper.xml(sql语句))
public Configuration parse() {
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
1.1.1 解析Mapper.xml
private void mapperElement(XNode parent) throws Exception {
if (parent != null) {
for (XNode child : parent.getChildren()) {
if ("package".equals(child.getName())) {
String mapperPackage = child.getStringAttribute("name");
configuration.addMappers(mapperPackage);
} else {
String resource = child.getStringAttribute("resource");
String url = child.getStringAttribute("url");
String mapperClass = child.getStringAttribute("class");
if (resource != null && url == null && mapperClass == null) {
ErrorContext.instance().resource(resource);
InputStream inputStream = Resources.getResourceAsStream(resource);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
mapperParser.parse();
} else if (resource == null && url != null && mapperClass == null) {
ErrorContext.instance().resource(url);
InputStream inputStream = Resources.getUrlAsStream(url);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments());
//将解析mybatis配置中的mapper节点,里面将解析mapper.xml中的sql
mapperParser.parse();
} else if (resource == null && url == null && mapperClass != null) {
Class<?> mapperInterface = Resources.classForName(mapperClass);
configuration.addMapper(mapperInterface);
} else {
throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
}
}
}
}
}
1.1.1.1 里面执行了(将sql信息封装到了MapperedStatement中(一个MapperedStatement代表了增删改查的详细信息),MappedStatement封装在了Configuration对象中)
builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
resultSetTypeEnum, flushCache, useCache, resultOrdered,
keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);

第一步结束后,最终返回一个 DefaultSqlSessionFactory(保存了Configuration,里面最重要的两个属性)
public class Configuration {
protected MapperRegistry mapperRegistry = new MapperRegistry(this); //用于生产mapper代理
protected final Map<String, MappedStatement> mappedStatements = new StrictMap<MappedStatement>("Mapped Statements collection");
}
2、通过工厂得到SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
2.1
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
2.1.1 返回一个 defaultExecutorType = ExecutorType.SIMPLE(默认),还要其他的(BATCH,REUSE),后面会根据这个创建不同的 Executor
configuration.getDefaultExecutorType()
2.1.2
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
//获取环境信息
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
//创建4大对象之一的Executor
final Executor executor = configuration.newExecutor(tx, execType);
//返回DefaultSqlSession(里面包含配置信息,和执行器)
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
closeTransaction(tx); // may have fetched a connection so lets call close()
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
2.1.2.1 根据 ExecutorType,创建不同的执行器,Executor是一个接口,规定了增删改查的所有的方法;
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
executor = new SimpleExecutor(this, transaction);
}
//是否配置了二级缓存
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
//执行拦截器链(interceptorChain封装了拦截器列表),非常重要,每一个executory的创建都要被拦截
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
2.1.2.1.1
private final List<Interceptor> interceptors = new ArrayList<Interceptor>();
public Object pluginAll(Object target) {
for (Interceptor interceptor : interceptors) {
target = interceptor.plugin(target); //执行每一个拦截器的plugin方法,如果没有就跳过
}
return target;
}
第2步主要就是返回了一个 DefaultSqlSession,里面创建了执行器,封装到DefaultSqlSession中
3、获取代理对象,代理对象去执行增删改查
UserDao mapper = sqlSession.getMapper(UserDao.class);
3.1
public <T> T getMapper(Class<T> type) {
return configuration.<T>getMapper(type, this);
}
3.1.1
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return mapperRegistry.getMapper(type, sqlSession);
}
3.1.1.1
@SuppressWarnings("unchecked")
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
//knownMappers通过type,获得代理对象
final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
if (mapperProxyFactory == null)
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
try {
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception e) {
throw new BindingException("Error getting mapper instance. Cause: " + e, e);
}
}
3.1.1.1.1
mapperProxyFactory.newInstance(sqlSession);
3.1.1.1.1.1 public class MapperProxy<T> implements InvocationHandler, Serializable (MapperProxy就是一个InvocationHander)
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
3.1.1.1.1.1.1 最终创建代理
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}

浙公网安备 33010602011771号