MyBatis 配置文件解析过程中,主要运用了以下几种设计模式
1. 建造者模式 (Builder Pattern):
- 应用场景:
SqlSessionFactoryBuilder
和XMLConfigBuilder
类都体现了建造者模式。 - 模式描述: 建造者模式将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。它允许用户一步一步地构造复杂对象,而无需知道内部构建细节。
- MyBatis 中的应用:
SqlSessionFactoryBuilder
: 作为SqlSessionFactory
的建造者,它抽象了SqlSessionFactory
的创建过程。开发者通过SqlSessionFactoryBuilder.build()
方法,传入不同的配置源 (如InputStream
,Configuration
对象),就可以构建出SqlSessionFactory
实例,而无需了解SqlSessionFactory
内部的复杂初始化过程。XMLConfigBuilder
: 作为Configuration
对象的建造者,它负责解析 XML 配置文件 (mybatis-config.xml
),并逐步构建Configuration
对象。XMLConfigBuilder.parse()
方法封装了对 XML 配置文件的解析、验证、以及将配置信息填充到Configuration
对象中的复杂流程。
2. 工厂模式 (Factory Pattern):
- 应用场景:
SqlSessionFactoryBuilder
本身也可以被视为SqlSessionFactory
的工厂。MapperProxyFactory
是 Mapper 代理对象的工厂。 - 模式描述: 工厂模式提供了一种创建对象的最佳方式,将对象的创建逻辑封装在一个工厂类中,客户端代码只需要通过工厂类来获取对象,而无需关心对象的具体创建过程。
- MyBatis 中的应用:
SqlSessionFactoryBuilder
: 可以看作是SqlSessionFactory
的抽象工厂。SqlSessionFactoryBuilder
提供了build()
方法,用于创建SqlSessionFactory
实例,隐藏了SqlSessionFactory
的具体实现类 (DefaultSqlSessionFactory
) 和创建细节。MapperProxyFactory
: 作为 Mapper 接口代理对象的工厂,MapperProxyFactory
负责创建 Mapper 接口的动态代理对象 (使用 JDK 动态代理或 CGLIB)。MapperProxyFactory.newInstance()
方法隐藏了代理对象的创建细节,客户端代码只需要通过MapperRegistry.getMapper()
方法就可以获取 Mapper 代理对象。
3. 模板方法模式 (Template Method Pattern):
- 应用场景: 在
XMLConfigBuilder
和XMLMapperBuilder
的 XML 解析过程中,存在一些通用的解析流程,但具体的解析步骤可能因 XML 元素类型而异。 模板方法模式被用于定义通用的解析框架,并将具体的解析步骤延迟到子类实现。 - 模式描述: 模板方法模式在一个抽象类中定义一个算法的骨架,并将某些步骤延迟到子类中实现。 这样,子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
- MyBatis 中的应用 (推测,更偏内部实现):
- XML 解析流程:
XMLConfigBuilder
和XMLMapperBuilder
的parse()
方法可能使用了模板方法模式。parse()
方法定义了 XML 解析的通用流程 (例如:加载 XML -> 解析根元素 -> 顺序解析子元素 -> 构建对象),而具体的子元素解析逻辑 (例如解析<properties>
,<settings>
,<mappers>
,<select>
,<resultMap>
等) 则可能由不同的子类或策略类来实现。 (需要更深入源码才能确认,但模板方法模式很适合这种场景)。
- XML 解析流程:
4. 策略模式 (Strategy Pattern):
- 应用场景: MyBatis 配置文件中,某些配置项可能存在多种策略或实现方式,例如缓存实现类型 (
<cache type="...">
),事务管理器类型 (<transactionManager type="...">
),数据源类型 (<dataSource type="...">
) 等。 策略模式被用于允许在运行时动态地选择和切换不同的策略实现。 - 模式描述: 策略模式定义了一系列算法,并将每个算法封装到独立的策略类中,使得算法可以独立于使用它的客户端代码而变化。
- MyBatis 中的应用:
- 缓存策略 (
<cache type="...">
): MyBatis 允许配置不同的缓存实现类型 (例如PERPETUAL
,LRU
,FIFO
,WEAK
,SOFT
, 或自定义缓存实现)。 每种缓存类型都对应一个Cache
接口的实现类 (策略类)。 在解析<cache>
元素时,XMLConfigBuilder
会根据type
属性的值,动态地选择并创建对应的Cache
实现类实例。 - 事务管理器类型 (
<transactionManager type="...">
): MyBatis 支持不同的事务管理器类型 (例如JDBC
,MANAGED
, 或自定义事务管理器)。 每种事务管理器类型都对应一个TransactionFactory
接口的实现类 (策略类)。 在解析<transactionManager>
元素时,XMLConfigBuilder
会根据type
属性的值,动态地选择并创建对应的TransactionFactory
实现类实例。 - 数据源类型 (
<dataSource type="...">
): MyBatis 支持不同的数据源类型 (例如UNPOOLED
,POOLED
,JNDI
, 或自定义数据源实现)。 每种数据源类型都对应一个DataSourceFactory
接口的实现类 (策略类)。 在解析<dataSource>
元素时,XMLConfigBuilder
会根据type
属性的值,动态地选择并创建对应的DataSourceFactory
实现类实例。
- 缓存策略 (
5. 注册器模式 (Registry Pattern) (可以归类到工厂模式的变种):
- 应用场景:
TypeHandlerRegistry
和MapperRegistry
本身可以看作是注册器模式的应用。 它们负责注册和管理特定类型的组件 (TypeHandler 和 Mapper 接口)。 - 模式描述: 注册器模式用于创建一个集中管理特定类型对象的注册中心,并提供根据键值获取已注册对象的能力。
- MyBatis 中的应用:
TypeHandlerRegistry
: 作为 TypeHandler 的注册中心,负责注册和管理所有 TypeHandler,并提供getTypeHandler()
方法根据 Java 类型和 JDBC 类型查找 TypeHandler。MapperRegistry
: 作为 Mapper 接口的注册中心,负责注册和管理所有 Mapper 接口,并提供getMapper()
方法根据 Mapper 接口类型获取 Mapper 代理对象.
总结:
MyBatis 配置文件解析过程巧妙地运用了多种设计模式,主要包括:
- 建造者模式 (Builder Pattern): 用于构建复杂的
SqlSessionFactory
和Configuration
对象。 - 工厂模式 (Factory Pattern): 用于创建
SqlSessionFactory
和 Mapper 代理对象。 - 模板方法模式 (Template Method Pattern): 可能用于定义 XML 解析的通用流程 (更偏内部实现)。
- 策略模式 (Strategy Pattern): 用于支持多种可切换的配置策略 (缓存策略、事务管理器类型、数据源类型等)。
- 注册器模式 (Registry Pattern): 用于管理特定类型的组件 (TypeHandler 和 Mapper 接口)。