知其然要知其所以然,探索每一个知识点背后的意义,你知道的越多,你不知道的越多,一起学习,一起进步,如果文章感觉对您有用的话,关注、收藏、点赞,有困惑的地方请评论,我们一起交流!
一、MyBatis 启动加载环境配置流程图
二、流程详解与源码分析
1. 入口:SqlSessionFactoryBuilder.build()
- 作用:读取配置文件流,初始化
XMLConfigBuilder
。 - 源码路径:
org.apache.ibatis.session.SqlSessionFactoryBuilder
public SqlSessionFactory build(Reader reader, String environment, Properties properties) { XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties); return build(parser.parse()); }
2. 解析全局配置:XMLConfigBuilder.parse()
- 源码路径:
org.apache.batis.builder.xml.XMLConfigBuilder
- 关键方法:
parse()
逐级解析配置文件节点:public Configuration parse() { // 解析 <configuration> 根节点 parseConfiguration(parser.evalNode("/configuration")); return configuration; } private void parseConfiguration(XNode root) { // 依次解析各配置块 propertiesElement(root.evalNode("properties")); environmentsElement(root.evalNode("environments")); typeAliasesElement(root.evalNode("typeAliases")); pluginElement(root.evalNode("plugins")); mapperElement(root.evalNode("mappers")); }
3. 解析环境配置(environments)
- 源码路径:
XMLConfigBuilder.environmentsElement()
- 功能:加载数据源和事务管理器。
- 核心对象:
Environment
:包含DataSource
和TransactionFactory
。TransactionFactory
:决定事务管理方式(JDBC/MANAGED)。
4. 解析类型别名(typeAliases)
- 源码路径:
XMLConfigBuilder.typeAliasesElement()
- 功能:注册 Java 类型别名(如
com.example.User
→User
)。 - 核心对象:
TypeAliasRegistry
,内部维护Map<String, Class<?>>
。
5. 解析插件(plugins)
- 源码路径:
XMLConfigBuilder.pluginElement()
- 功能:加载拦截器(如分页插件),构建拦截器链。
- 核心对象:
InterceptorChain
:通过动态代理包装目标对象(如Executor
)。- 示例:
@Intercepts
注解定义拦截点。
6. 解析映射器(mappers)
- 源码路径:
XMLConfigBuilder.mapperElement()
- 功能:加载 Mapper 接口或 XML 文件,绑定 SQL 语句。
- 关键分支逻辑:
// 处理 <mapper> 标签的不同配置方式 if (resource != null) { // 从类路径加载 XML 文件 InputStream inputStream = Resources.getResourceAsStream(resource); XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, ...); mapperParser.parse(); } else if (url != null) { // 从 URL 加载 XML 文件 } else if (mapperClass != null) { // 注册 Mapper 接口 configuration.addMapper(mapperClass); }
7. 解析 Mapper XML:XMLMapperBuilder.parse()
- 源码路径:
org.apache.ibatis.builder.xml.XMLMapperBuilder
- 关键逻辑:
public void parse() { // 解析 <mapper> 根节点 configurationElement(parser.evalNode("/mapper")); } private void configurationElement(XNode context) { // 解析命名空间 String namespace = context.getStringAttribute("namespace"); // 解析 <select>, <insert> 等 SQL 节点 buildStatementFromContext(context.evalNodes("select|insert|update|delete")); }
8. 绑定 Mapper 接口
- 源码路径:
org.apache.ibatis.binding.MapperRegistry
- 核心方法:
addMapper()
public <T> void addMapper(Class<T> type) { MapperProxyFactory<T> proxyFactory = new MapperProxyFactory<>(type); knownMappers.put(type, proxyFactory); // 解析接口方法对应的 SQL 语句 MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type); parser.parse(); }
9. 生成 MappedStatement
- 源码路径:
org.apache.ibatis.builder.MapperBuilderAssistant
- 核心逻辑:将 XML 或注解中的 SQL 定义转换为
MappedStatement
。public MappedStatement addMappedStatement( String id, SqlSource sqlSource, ...) { // 构建 MappedStatement 并注册到 Configuration MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration, id, ...); MappedStatement statement = statementBuilder.build(); configuration.addMappedStatement(statement); return statement; }
10. 构建 SqlSessionFactory
- 最终产物:
DefaultSqlSessionFactory
。 - 源码路径:
SqlSessionFactoryBuilder.build()
public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); }
三、关键类图
SqlSessionFactoryBuilder
│
└── build() → XMLConfigBuilder
│
└── parse() → Configuration
│
├── Environment
├── MappedStatement
├── TypeAliasRegistry
└── InterceptorChain
│
└── Plugin.wrap() → 动态代理对象
四、调试技巧
-
断点位置:
XMLConfigBuilder.parseConfiguration()
:跟踪全局配置解析。XMLMapperBuilder.parse()
:观察 Mapper XML 的加载过程。MapperRegistry.addMapper()
:分析 Mapper 接口的动态代理生成。
-
日志输出: 在
mybatis-config.xml
中开启日志,查看配置加载细节:<configuration> <settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> </configuration>
五、总结
通过上述流程,MyBatis 完成了从配置文件到运行时对象的转换,核心在于:
- 全局配置中心:
Configuration
对象存储所有配置信息。 - 动态代理机制:
MapperProxy
实现接口方法与 SQL 的绑定。 - 插件扩展:
InterceptorChain
支持功能增强(如分页、监控)。