MyBatis设计模式之构建者、工厂、代理模式
一、MyBatis整体架构与设计模式
MyBatis作为一款优秀的持久层框架,其代码中运用了多种经典的设计模式。这些设计模式的应用,使得MyBatis具有良好的扩展性、灵活性和可维护性。
1.1 MyBatis整体架构
MyBatis采用了分层架构设计,从上到下主要包括:
- 应用层:用户应用程序
- 接口层:SqlSession、Mapper接口
- 核心处理层:SQL解析、执行、结果映射
- 基础支撑层:反射、类型处理、日志、缓存、事务等
- 数据层:数据源、连接池、JDBC驱动
在这些层次中,设计模式被广泛应用,贯穿整个框架。
1.2 MyBatis中的主要设计模式
MyBatis中使用的设计模式包括:
- 构建者模式(Builder Pattern) :SqlSessionFactoryBuilder、CacheBuilder、ParameterExpression等
- 工厂模式(Factory Pattern) :SqlSessionFactory、MapperProxyFactory、ObjectFactory、DataSourceFactory等
- 代理模式(Proxy Pattern) :MapperProxy、Plugin、ConnectionLogger、PreparedStatementLogger等
- 组合模式(Composite Pattern) :SqlNode、DynamicContext等
- 模板方法模式(Template Method Pattern) :BaseExecutor、SimpleExecutor、BatchExecutor等
- 适配器模式(Adapter Pattern) :Log接口及其适配器
- 装饰器模式(Decorator Pattern) :CachingExecutor、Executor的包装
- 策略模式(Strategy Pattern) :RoutingStatementHandler、ResultSetHandler等
- 迭代器模式(Iterator Pattern) :PropertyTokenizer、DefaultCursor等
- 责任链模式(Chain of Responsibility) :Interceptor链、Plugin链

本文将重点讲解构建者模式、工厂模式和代理模式在MyBatis中的应用。
二、构建者模式(Builder Pattern)
构建者模式是一种创建型设计模式,它允许你分步骤创建复杂对象。该模式使你可以使用相同的创建代码生成不同类型和形式的对象。
2.1 SqlSessionFactoryBuilder
SqlSessionFactoryBuilder是MyBatis中最典型的构建者模式应用。它负责从XML配置文件或Configuration对象构建SqlSessionFactory。
2.1.1 基本用法
ini
// 从XML文件构建
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 从Configuration对象构建
Configuration config = new Configuration();
config.addMapper(UserMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
2.1.2 源码分析
typescript
public class SqlSessionFactoryBuilder {
// 从InputStream构建
public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream, null, null);
}
public SqlSessionFactory build(InputStream inputStream, String environment) {
return build(inputStream, environment, null);
}
public SqlSessionFactory build(InputStream inputStream, Properties properties) {
return build(inputStream, null, properties);
}
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
// 1. 解析XML配置文件,创建XMLConfigBuilder
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
// 2. 解析配置并构建Configuration对象
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException e) {
// ignore
}
}
}
// 从Configuration构建
public SqlSessionFactory build(Configuration config) {
// 3. 创建DefaultSqlSessionFactory
return new DefaultSqlSessionFactory(config);
}
// 从Reader构建
public SqlSessionFactory build(Reader reader) {
return build(reader, null, null);
}
public SqlSessionFactory build(Reader reader, String environment) {
return build(reader, environment, null);
}
public SqlSessionFactory build(Reader reader, Properties properties) {
return build(reader, null, properties);
}
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException e) {
// ignore
}
}
}
}
2.1.3 构建过程分析
SqlSessionFactoryBuilder的构建过程可以分为以下几个步骤:
- 加载配置文件:从InputStream或Reader加载XML配置文件
- 创建解析器:创建XMLConfigBuilder解析XML配置
- 解析配置:解析XML配置文件,构建Configuration对象
- 创建工厂:使用Configuration对象创建SqlSessionFactory

2.2 XMLConfigBuilder
XMLConfigBuilder是实际的构建者,负责解析XML配置文件并构建Configuration对象。
scala
public class XMLConfigBuilder extends BaseBuilder {
private boolean parsed;
private final XPathParser parser;
private String environment;
public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {
this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);
}
// 解析配置
public Configuration parse() {
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
// 解析configuration节点
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
private void parseConfiguration(XNode root) {
try {
// 解析各个配置项
propertiesElement(root.evalNode("properties"));
typeAliasesElement(root.evalNode("typeAliases"));
pluginsElement(root.evalNode("plugins"));
objectFactoryElement(root.evalNode("objectFactory"));
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
reflectionFactoryElement(root.evalNode("reflectionFactory"));
settingsElement(root.evalNode("settings"));
environmentsElement(root.evalNode("environments"));
databaseIdProviderElement(root.evalNode("databaseIdProvider"));
typeHandlerElement(root.evalNode("typeHandlers"));
mapperElement(root.evalNode("mappers"));
} catch (Exception e) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
}
}
}
2.3 构建者模式的优势
- 分步构建:将复杂对象的构建过程分解为多个步骤
- 代码复用:相同的构建代码可以创建不同的对象
- 封装复杂度:隐藏对象创建的复杂细节
- 灵活配置:支持多种不同的配置方式
2.4 其他构建者模式应用
除了SqlSessionFactoryBuilder,MyBatis中还有其他构建者模式的应用:
2.4.1 CacheBuilder
typescript
public class CacheBuilder {
private final String id;
private Class<? extends Cache> implementation;
private List<Class<? extends Cache>> decorators;
private Integer size;
private Long clearInterval;
private boolean readWrite;
private Properties properties;
public Cache build() {
// 设置默认实现
setDefaultImplementations();
// 创建缓存
Cache cache = newBaseCacheInstance(implementation, id);
setCacheProperties(cache);
// 应用装饰器
for (Class<? extends Cache> decorator : decorators) {
cache = newCacheDecoratorInstance(decorator, cache);
setCacheProperties(cache);
}
return cache;
}
}
2.4.2 ParameterExpression
typescript
public class ParameterExpression implements Iterator<ParameterExpression> {
// 构建者模式用于解析参数表达式
public ParameterExpression(String expression) {
parseExpression(expression);
}
private void parseExpression(String expression) {
// 解析属性表达式
}
}
三、工厂模式(Factory Pattern)
工厂模式是一种创建型设计模式,它提供了创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
3.1 SqlSessionFactory
SqlSessionFactory是MyBatis中最核心的工厂接口,负责创建SqlSession对象。
3.1.1 接口定义
scss
public interface SqlSessionFactory {
// 创建SqlSession的各种方法
SqlSession openSession();
SqlSession openSession(boolean autoCommit);
SqlSession openSession(Connection connection);
SqlSession openSession(TransactionIsolationLevel level);
SqlSession openSession(ExecutorType execType);
SqlSession openSession(ExecutorType execType, boolean autoCommit);
SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
SqlSession openSession(ExecutorType execType, Connection connection);
Configuration getConfiguration();
}
3.1.2 DefaultSqlSessionFactory
java
public class DefaultSqlSessionFactory implements SqlSessionFactory {
private final Configuration configuration;
public DefaultSqlSessionFactory(Configuration configuration) {
this.configuration = configuration;
}
@Override
public SqlSession openSession() {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
@Override
public SqlSession openSession(boolean autoCommit) {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit);
}
@Override
public SqlSession openSession(ExecutorType execType) {
return openSessionFromDataSource(execType, null, false);
}
@Override
public SqlSession openSession(TransactionIsolationLevel level) {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), level, false);
}
private SqlSession openSessionFromDataSource(ExecutorType execType,
TransactionIsolationLevel level,
boolean autoCommit) {
Transaction tx = null;
try {
// 1. 获取环境配置
Environment environment = configuration.getEnvironment();
// 2. 获取事务工厂
TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
// 3. 创建事务对象
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
// 4. 创建执行器
Executor executor = configuration.newExecutor(tx, execType);
// 5. 创建SqlSession
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
closeTransaction(tx);
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
}

3.2 MapperProxyFactory
MapperProxyFactory负责创建Mapper接口的代理对象。
3.2.1 源码分析
typescript
public class MapperProxyFactory<T> {
private final Class<T> mapperInterface;
private final Map<Method, MapperMethod> methodCache = new ConcurrentHashMap<>();
public MapperProxyFactory(Class<T> mapperInterface) {
this.mapperInterface = mapperInterface;
}
public Class<T> getMapperInterface() {
return mapperInterface;
}
public Map<Method, MapperMethod> getMethodCache() {
return methodCache;
}
@SuppressWarnings("unchecked")
protected T newInstance(MapperProxy<T> mapperProxy) {
// 使用JDK动态代理创建代理对象
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(),
new Class[] { mapperInterface },
mapperProxy);
}
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
}
3.2.2 使用示例
typescript
// MapperRegistry中注册Mapper
public <T> void addMapper(Class<T> type) {
if (type.isInterface()) {
if (hasMapper(type)) {
throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
}
boolean loadCompleted = false;
try {
// 创建MapperProxyFactory并注册
knownMappers.put(type, new MapperProxyFactory<>(type));
// 解析注解
MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
parser.parse();
loadCompleted = true;
} finally {
if (!loadCompleted) {
knownMappers.remove(type);
}
}
}
}
// 获取Mapper实例
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
}
try {
// 通过工厂创建Mapper代理对象
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception e) {
throw new BindingException("Error getting mapper instance. Cause: " + e, e);
}
}
3.3 ObjectFactory
ObjectFactory是MyBatis的对象工厂,负责创建对象实例。
3.3.1 接口定义
swift
public interface ObjectFactory {
// 创建对象
<T> T create(Class<T> type);
// 有参构造创建对象
<T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs);
// 判断是否是集合类型
<T> boolean isCollection(Class<T> type);
}
3.3.2 DefaultObjectFactory
typescript
public class DefaultObjectFactory implements ObjectFactory {
@Override
public <T> T create(Class<T> type) {
return create(type, null, null);
}
@SuppressWarnings("unchecked")
@Override
public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
// 1. 解析集合类型
Class<?> classToCreate = resolveInterface(type);
// 2. 使用构造器创建实例
return (T) instantiateClass(classToCreate, constructorArgTypes, constructorArgs);
}
private <T> T instantiateClass(Class<T> type, List<Class<?>> constructorArgTypes,
List<Object> constructorArgs) {
try {
Constructor<T> constructor;
// 有参构造
if (constructorArgTypes == null || constructorArgs == null) {
constructor = type.getDeclaredConstructor();
if (!constructor.isAccessible()) {
constructor.setAccessible(true);
}
return constructor.newInstance();
} else {
// 查找匹配的构造器
constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[0]));
if (!constructor.isAccessible()) {
constructor.setAccessible(true);
}
return constructor.newInstance(constructorArgs.toArray(new Object[0]));
}
} catch (Exception e) {
// 处理异常
}
}
@Override
public <T> boolean isCollection(Class<T> type) {
return Collection.class.isAssignableFrom(type);
}
}
3.4 工厂模式的优势
- 解耦:调用者不需要知道对象创建的细节
- 扩展性:新增产品类时不需要修改现有代码
- 复用性:工厂类可以被多个客户端复用
- 封装性:封装了对象创建的复杂逻辑
四、代理模式(Proxy Pattern)
代理模式是一种结构型设计模式,它允许你提供对象的替代品或占位符。代理控制着对原对象的访问,并允许在将请求提交给对象前后进行一些处理。
4.1 MapperProxy
MapperProxy是MyBatis中最核心的代理模式应用,它为Mapper接口创建代理对象,拦截方法调用并执行相应的SQL操作。
4.1.1 源码分析
kotlin
public class MapperProxy<T> implements InvocationHandler {
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;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 1. 如果是Object类的方法,直接执行
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
}
// 2. 获取MapperMethod
final MapperMethod mapperMethod = cachedMapperMethod(method);
// 3. 执行Mapper方法
return mapperMethod.execute(sqlSession, args);
}
private MapperMethod cachedMapperMethod(Method method) {
return methodCache.computeIfAbsent(method,
k -> new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()));
}
}
4.1.2 MapperMethod
ini
public class MapperMethod {
private final SqlCommand command;
private final MethodSignature method;
public MapperMethod(Class<?> mapperInterface, Method method, Configuration config) {
this.command = new SqlCommand(config, mapperInterface, method);
this.method = new MethodSignature(config, mapperInterface, method);
}
public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
switch (command.getType()) {
case INSERT: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.insert(command.getName(), param));
break;
}
case UPDATE: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.update(command.getName(), param));
break;
}
case DELETE: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.delete(command.getName(), param));
break;
}
case SELECT:
if (method.returnsVoid() && method.hasResultHandler()) {
executeWithResultHandler(sqlSession, args);
result = null;
} else if (method.returnsMany()) {
result = executeForMany(sqlSession, args);
} else if (method.returnsMap()) {
result = executeForMap(sqlSession, args);
} else if (method.returnsCursor()) {
result = executeForCursor(sqlSession, args);
} else {
Object param = method.convertArgsToSqlCommandParam(args);
result = sqlSession.selectOne(command.getName(), param);
if (method.returnsOptional()
&& (result == null || !method.getReturnType().equals(result.getClass()))) {
result = Optional.ofNullable(result);
}
}
break;
case FLUSH:
result = sqlSession.flushStatements();
break;
default:
throw new BindingException("Unknown execution method for: " + command.getName());
}
if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
throw new BindingException("Mapper method '" + command.getName()
+ " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
}
return result;
}
}

4.2 Plugin拦截器
Plugin是MyBatis的插件机制的核心,它通过动态代理实现对目标对象的拦截。
4.2.1 Interceptor接口
typescript
public interface Interceptor {
// 拦截方法
Object intercept(Invocation invocation) throws Throwable;
// 创建代理对象
default Object plugin(Object target) {
return Plugin.wrap(target, this);
}
// 设置属性
default void setProperties(Properties properties) {
// NOP
}
}
4.2.2 Plugin类
typescript
public class Plugin implements InvocationHandler {
private final Object target;
private final Interceptor interceptor;
private final Map<Class<?>, Set<Method>> signatureMap;
private Plugin(Object target, Interceptor interceptor, Map<Class<?>, Set<Method>> signatureMap) {
this.target = target;
this.interceptor = interceptor;
this.signatureMap = signatureMap;
}
public static Object wrap(Object target, Interceptor interceptor) {
// 1. 获取拦截的类和方法签名
Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
Class<?> type = target.getClass();
// 2. 获取所有需要拦截的接口
Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
// 3. 如果有需要拦截的接口,创建代理对象
if (interfaces.length > 0) {
return Proxy.newProxyInstance(
type.getClassLoader(),
interfaces,
new Plugin(target, interceptor, signatureMap));
}
return target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
// 4. 检查当前方法是否需要被拦截
Set<Method> methods = signatureMap.get(method.getDeclaringClass());
if (methods != null && methods.contains(method)) {
// 5. 调用拦截器的intercept方法
return interceptor.intercept(new Invocation(target, method, args));
}
// 6. 不需要拦截,直接调用目标方法
return method.invoke(target, args);
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error: " + e, e);
}
}
private static Map<Class<?>, Set<Method>> getSignatureMap(Interceptor interceptor) {
// 获取@Intercepts注解
Intercepts interceptsAnnotation = interceptor.getClass().getAnnotation(Intercepts.class);
if (interceptsAnnotation == null) {
throw new PluginException("No @Intercepts annotation was found in interceptor " + interceptor.getClass().getName());
}
Signature[] sigs = interceptsAnnotation.value();
Map<Class<?>, Set<Method>> signatureMap = new HashMap<>();
for (Signature sig : sigs) {
Set<Method> methods = signatureMap.computeIfAbsent(sig.type(), k -> new HashSet<>());
try {
Method method = sig.type().getMethod(sig.method(), sig.args());
methods.add(method);
} catch (NoSuchMethodException e) {
throw new PluginException("Could not find method on " + sig.type() + " named " + sig.method() + ". Cause: " + e, e);
}
}
return signatureMap;
}
private static Class<?>[] getAllInterfaces(Class<?> type, Map<Class<?>, Set<Method>> signatureMap) {
Set<Class<?>> interfaces = new HashSet<>();
while (type != null) {
for (Class<?> c : type.getInterfaces()) {
if (signatureMap.containsKey(c)) {
interfaces.add(c);
}
}
type = type.getSuperclass();
}
return interfaces.toArray(new Class<?>[0]);
}
}
4.2.3 插件使用示例
less
@Intercepts({
@Signature(type = Executor.class,
method = "update",
args = {MappedStatement.class, Object.class}),
@Signature(type = Executor.class,
method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
})
public class MyPlugin implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 前置处理
System.out.println("Before: " + invocation.getMethod().getName());
// 执行目标方法
Object result = invocation.proceed();
// 后置处理
System.out.println("After: " + invocation.getMethod().getName());
return result;
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
// 读取配置
}
}
4.3 代理模式的优势
- 职责清晰:将日志、事务等横切关注点与业务逻辑分离
- 灵活性:可以在不修改原始对象的情况下增加功能
- 可扩展性:通过插件机制轻松扩展框架功能
- 解耦:调用者不需要知道代理的存在
五、设计模式的协同应用
在MyBatis中,多种设计模式往往协同工作,共同完成复杂的功能。
5.1 创建SqlSession的完整流程
创建SqlSession的过程涉及多个设计模式的协同:
- 构建者模式:SqlSessionFactoryBuilder构建Configuration
- 工厂模式:SqlSessionFactory创建SqlSession
- 代理模式:MapperProxy创建Mapper代理对象
ini
// 1. 构建者模式:构建SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(Resources.getResourceAsStream("mybatis-config.xml"));
// 2. 工厂模式:创建SqlSession
SqlSession session = factory.openSession();
// 3. 代理模式:获取Mapper代理对象
UserMapper mapper = session.getMapper(UserMapper.class);
5.2 执行SQL的完整流程
执行SQL的过程也涉及多个设计模式的协同:
- 代理模式:MapperProxy拦截方法调用
- 工厂模式:SqlSession创建Statement
- 模板方法模式:BaseExecutor定义执行流程
- 策略模式:不同的Executor使用不同的执行策略

六、最佳实践
6.1 使用构建者模式
当你需要创建复杂对象时,可以考虑使用构建者模式:
typescript
public class ComplexObjectBuilder {
private ComplexObject object = new ComplexObject();
public ComplexObjectBuilder withProperty1(String value) {
object.setProperty1(value);
return this;
}
public ComplexObjectBuilder withProperty2(int value) {
object.setProperty2(value);
return this;
}
public ComplexObject build() {
return object;
}
}
// 使用
ComplexObject obj = new ComplexObjectBuilder()
.withProperty1("value1")
.withProperty2(100)
.build();
6.2 使用工厂模式
当对象的创建逻辑复杂或需要根据配置创建不同实现时,使用工厂模式:
typescript
public interface ServiceFactory {
Service createService();
}
public class ServiceFactoryA implements ServiceFactory {
@Override
public Service createService() {
return new ServiceA();
}
}
public class ServiceFactoryB implements ServiceFactory {
@Override
public Service createService() {
return new ServiceB();
}
}
6.3 使用代理模式
当你需要在不修改原始对象的情况下添加功能时,使用代理模式:
typescript
public class ServiceProxy implements InvocationHandler {
private Object target;
public ServiceProxy(Object target) {
this.target = target;
}
public static <T> T createProxy(T target) {
return (T) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new ServiceProxy(target));
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 前置处理
System.out.println("Before: " + method.getName());
// 执行目标方法
Object result = method.invoke(target, args);
// 后置处理
System.out.println("After: " + method.getName());
return result;
}
}
七、总结
MyBatis作为一款优秀的持久层框架,其代码中大量运用了经典的设计模式。这些设计模式的应用,使得MyBatis具有良好的架构设计和可扩展性。
这些设计模式不是孤立存在的,而是相互配合,共同构建了MyBatis强大的功能体系。深入理解这些设计模式,不仅有助于我们更好地使用MyBatis,也能为我们自己的架构设计提供参考和借鉴。
