🥂(❁´◡`❁)您的点赞👍➕评论📝➕收藏⭐是作者创作的最大动力🤞
💖📕🎉🔥 支持我:点赞👍+收藏⭐️+留言📝欢迎留言讨论
🔥🔥🔥(源码 + 调试运行 + 问题答疑)🔥🔥🔥 有兴趣可以联系我
🔥🔥🔥 文末有往期免费源码,直接领取获取(无删减,无套路)
工厂模式赋能:MyBatis代理对象的诞生之地
-
《MyBatis代理工厂解密:SqlSession.getMapper()背后的三层架构》
-
《手写MyBatis核心:MapperProxyFactory如何孕育Mapper代理》
-
《从接口到实例:深度剖析MyBatis的Mapper代理生成链》
-
《SqlSession.getMapper()内部机制:代理工厂模式的完美实践》
-
《设计模式在MyBatis的应用:工厂模式如何解决代理复用问题》
代理工厂模式:MyBatis的Mapper生产线
引言: 在MyBatis中,SqlSession.getMapper()
如同魔法般将接口转为可执行对象。今天我们将揭开这魔法背后的三层架构,实现Mapper代理的工厂化生产。
一、三层架构实现:从接口到代理实例
核心类关系图
代码实现
1. MapperProxy - 代理逻辑核心
public class MapperProxy implements InvocationHandler {
private final SqlSession sqlSession;
private final Class<?> mapperInterface;
public MapperProxy(SqlSession sqlSession, Class<?> mapperInterface) {
this.sqlSession = sqlSession;
this.mapperInterface = mapperInterface;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) {
// 后续将实现SQL执行
System.out.println("代理方法: " + method.getName());
return null;
}
}
2. MapperProxyFactory - 代理对象工厂
public class MapperProxyFactory<T> {
private final Class<T> mapperInterface;
// 工厂缓存:避免重复创建相同接口的工厂
private static final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<>();
public MapperProxyFactory(Class<T> mapperInterface) {
this.mapperInterface = mapperInterface;
}
// 获取工厂实例(缓存优化)
public static <T> MapperProxyFactory<T> getInstance(Class<T> mapperInterface) {
return (MapperProxyFactory<T>) knownMappers.computeIfAbsent(
mapperInterface,
clazz -> new MapperProxyFactory<>(clazz)
);
}
// 创建代理对象
public T newInstance(SqlSession sqlSession) {
final MapperProxy proxy = new MapperProxy(sqlSession, mapperInterface);
return (T) Proxy.newProxyInstance(
mapperInterface.getClassLoader(),
new Class[]{mapperInterface},
proxy
);
}
}
3. SqlSession实现 - 用户入口
public class DefaultSqlSession implements SqlSession {
private final Configuration configuration;
public DefaultSqlSession(Configuration configuration) {
this.configuration = configuration;
}
@Override
public <T> T getMapper(Class<T> type) {
// 从配置中获取Mapper接口的工厂
MapperProxyFactory<T> factory = configuration.getMapperFactory(type);
return factory.newInstance(this);
}
}
二、工厂模式的价值解析
为什么需要MapperProxyFactory?
问题 | 无工厂方案 | 工厂方案 |
---|---|---|
对象复用 | 每次getMapper创建新代理 | 缓存代理实例 |
资源消耗 | 重复生成字节码 | 减少字节码生成开销 |
配置解耦 | 代理创建逻辑侵入SqlSession | 创建逻辑封装隔离 |
扩展性 | 添加新功能需修改入口类 | 可扩展工厂行为 |
SqlSession.getMapper()的核心作用
-
统一入口:用户获取Mapper的唯一标准方式
-
生命周期管理:绑定到当前SqlSession
-
资源整合:传递配置信息和数据库连接
-
类型安全:编译期检查接口类型
三、深度思考:工厂模式的设计哲学
三级缓存优化体系
-
MapperProxyFactory缓存
knownMappers
避免重复创建相同接口的工厂 -
代理实例缓存(可选扩展)
public class MapperProxyFactory<T> { private T proxyInstance; // 单例代理 public synchronized T newInstance(SqlSession sqlSession) { if (proxyInstance == null) { proxyInstance = createProxy(sqlSession); } return proxyInstance; } }
-
MapperMethod缓存 在
MapperProxy
中缓存方法对应的执行逻辑
MyBatis的工厂模式变体
设计原则体现
-
单一职责原则
-
SqlSession:提供操作入口
-
MapperProxyFactory:专注代理创建
-
MapperProxy:处理方法调用
-
-
开闭原则 新增Mapper接口无需修改工厂逻辑
结语: MapperProxyFactory
作为MyBatis代理体系的核心枢纽,通过工厂模式将复杂的代理创建过程封装简化。这种设计不仅提升了性能,更为框架的扩展性奠定了坚实基础。
往期免费源码 (无删减,无套路):🔥🔥🔥
https://pan.baidu.com/s/1sjAr08PU9Xe7MQf1gjGM5w?pwd=6666
「在线考试系统源码(含搭建教程)」 (无删减,无套路):🔥🔥🔥
链接:https://pan.quark.cn/s/96c4f00fdb43 提取码:WR6M
往期免费源码对应视频:
免费获取--SpringBoot+Vue宠物商城网站系统
🥂(❁´◡`❁)您的点赞👍➕评论📝➕收藏⭐是作者创作的最大动力🤞
💖📕🎉🔥 支持我:点赞👍+收藏⭐️+留言📝欢迎留言讨论
🔥🔥🔥(源码 + 调试运行 + 问题答疑)
🔥🔥🔥 有兴趣可以联系我