手写MyBatis第5弹:JDK动态代理与CGLIB的技术选型

🥂(❁´◡`❁)您的点赞👍➕评论📝➕收藏⭐是作者创作的最大动力🤞

💖📕🎉🔥 支持我:点赞👍+收藏⭐️+留言📝欢迎留言讨论

🔥🔥🔥(源码 + 调试运行 + 问题答疑)🔥🔥🔥  有兴趣可以联系我

🔥🔥🔥  文末有往期免费源码,直接领取获取(无删减,无套路)


CGLIB代理:MyBatis中的备选引擎

  1. 《MyBatis代理双引擎:JDK动态代理与CGLIB的技术选型》

  2. 《超越接口限制:CGLIB如何为MyBatis提供类代理能力》

  3. 《手写MyBatis高级篇:CGLIB代理实现懒加载黑科技》

  4. 《无接口也能代理!CGLIB在MyBatis插件中的应用揭秘》

  5. 《动态代理终极对决:JDK Proxy vs CGLIB的MyBatis实践》


CGLIB代理:MyBatis中的备选引擎

引言: 当JDK动态代理遇到无接口的类,CGLIB闪亮登场。本文通过手写CGLIB代理,揭示MyBatis在懒加载和插件系统中的类代理技术。


一、CGLIB核心组件解析

组件作用对应JDK代理
Enhancer代理生成器Proxy
MethodInterceptor方法拦截器InvocationHandler
CallbackFilter回调过滤器无直接对应

二、CGLIB代理实战:为User类增强

 
// 1. 引入依赖
 <dependency>
     <groupId>cglib</groupId>
     <artifactId>cglib</artifactId>
     <version>3.3.0</version>
 </dependency>
 ​
 // 2. 创建方法拦截器
 public class LogInterceptor implements MethodInterceptor {
     @Override
     public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) {
         System.out.println("【CGLIB拦截】方法: " + method.getName());
         
         // 不拦截toString方法
         if ("toString".equals(method.getName())) {
             return proxy.invokeSuper(obj, args);
         }
         
         // 模拟数据库懒加载
         if ("getPosts".equals(method.getName())) {
             System.out.println("触发懒加载...");
             return Collections.singletonList(new Post("CGLIB代理的帖子"));
         }
         
         return proxy.invokeSuper(obj, args);
     }
 }
 ​
 // 3. 生成代理对象
 public class CglibProxyFactory {
     public static <T> T createProxy(Class<T> targetClass) {
         Enhancer enhancer = new Enhancer();
         enhancer.setSuperclass(targetClass);
         enhancer.setCallback(new LogInterceptor());
         return (T) enhancer.create();
     }
 }
 ​
 // 4. 客户端调用
 public class Client {
     public static void main(String[] args) {
         // 代理普通类(非接口!)
         User userProxy = CglibProxyFactory.createProxy(User.class);
         
         System.out.println("代理类: " + userProxy.getClass());
         System.out.println("父类: " + userProxy.getClass().getSuperclass());
         
         // 触发拦截
         List<Post> posts = userProxy.getPosts();
         System.out.println(posts.get(0).getTitle());
     }
 }

控制台输出:

 代理类: class com.example.User$$EnhancerByCGLIB$$a1b2c3d4
 父类: class com.example.User
 【CGLIB拦截】方法: getPosts
 触发懒加载...
 CGLIB代理的帖子

三、CGLIB代理原理剖析

字节码生成过程:

  1. 继承目标类生成子类

  2. 重写非final方法

  3. 方法中调用MethodInterceptor

  4. 通过FastClass机制加速调用


四、MyBatis中的代理技术选型

JDK代理 vs CGLIB 对比
特性JDK动态代理CGLIB
代理对象实现接口继承目标类
速度调用快生成快
限制需接口无法代理final类/方法
依赖JVM内置第三方库
MyBatis的代理策略

  1. Mapper接口:JDK动态代理(100%) 因为Mapper都是接口,JDK代理最合适

  2. 懒加载:CGLIB代理(可选)

     // 配置开启CGLIB懒加载代理
     <setting name="lazyLoadingEnabled" value="true"/>
     <setting name="proxyFactory" value="CGLIB"/>
  3. 插件系统:CGLIB特殊应用 某些插件需要代理目标对象本身


五、CGLIB实战:手写懒加载代理

 public class LazyLoaderInterceptor implements MethodInterceptor {
     private volatile boolean loaded = false;
     private Object realValue;
     
     @Override
     public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) {
         // 触发加载条件:首次调用getter方法
         if (method.getName().startsWith("get") && !loaded) {
             synchronized (this) {
                 if (!loaded) {
                     System.out.println("【CGLIB】执行数据库查询...");
                     realValue = loadFromDatabase(); // 实际数据库操作
                     loaded = true;
                 }
             }
         }
         return loaded ? method.invoke(realValue, args) : null;
     }
 }

结语: CGLIB作为JDK动态代理的重要补充,为MyBatis提供了处理非接口代理的能力。虽然在Mapper代理中不是主角,但在懒加载等高级特性中发挥着不可替代的作用,展现了MyBatis灵活的技术选型智慧。


往期免费源码 (无删减,无套路):🔥🔥🔥  

https://pan.baidu.com/s/1sjAr08PU9Xe7MQf1gjGM5w?pwd=6666​

「在线考试系统源码(含搭建教程)」 (无删减,无套路):🔥🔥🔥  

链接:https://pan.quark.cn/s/96c4f00fdb43 提取码:WR6M


往期免费源码对应视频:

免费获取--SpringBoot+Vue宠物商城网站系统

🥂(❁´◡`❁)您的点赞👍➕评论📝➕收藏⭐是作者创作的最大动力🤞

💖📕🎉🔥 支持我:点赞👍+收藏⭐️+留言📝欢迎留言讨论

🔥🔥🔥(源码 + 调试运行 + 问题答疑)

🔥🔥🔥  有兴趣可以联系我

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值