连载中 6/18

AOP(上):JDK 动态代理与 CGLIB

2026-11-05 · 41 阅读 · 0 评论 · 0 赞

代理从哪来

第 1 篇立了认知:容器里住的是代理。本篇看代理的真身。动态代理不是 Spring 的发明,是 Java 层面的能力,Spring 用了两条路实现:JDK 动态代理与 CGLIB。

JDK 动态代理:接口的影子

运行时生成一个实现目标接口的代理类(类名形如 $Proxy0),所有方法调用统一转发给 InvocationHandler——手写二十行看穿本质:

UserService target = new UserServiceImpl();

UserService proxy = (UserService) Proxy.newProxyInstance(
        target.getClass().getClassLoader(),
        target.getClass().getInterfaces(),
        (p, method, args) -> {
            long start = System.currentTimeMillis();
            Object result = method.invoke(target, args);   // 反射调用原方法
            System.out.println(method.getName() + " 耗时:" + (System.currentTimeMillis() - start));
            return result;
        });

proxy.query();   // 调的是代理 → 计时逻辑生效;target.query() 则完全不会

硬性前提:目标必须实现接口——代理类的骨架是 implements,没有接口就没地方安放方法转发。

CGLIB:子类的偷天换日

没有接口怎么办?CGLIB 运行时生成目标类的子类,重写方法织入拦截器(MethodInterceptor)。也正因为靠继承,它代理不了 final 类和 final 方法(无法继承与重写),private 方法同样不在拦截范围。两个常见误区顺便纠正:其一,「有接口用 JDK、没接口用 CGLIB」是老版 Spring 的分流逻辑,Spring Boot 2.x 起 spring.aop.proxy-target-class 默认 true,全程默认 CGLIB,接口有无不再是分水岭;其二,CGLIB 用 FastClass 机制(给方法建索引直接调用,绕开反射)把性能做了上去,现代版本两者差距可忽略,选型不必纠结。

从原理看懂自调用失效

现在可以用原理重述第 1 篇的事故:拦截的入口在代理对象的方法调用上(InvocationHandler 或 MethodInterceptor)。类内部 this.audit() 里的 this 是原始对象而不是代理,调用根本没经过拦截器入口——增强自然消失。JDK 代理与 CGLIB 代理一视同仁。原理懂了,失效场景不用背,推都推得出来。

两条代理的路铺好了。但 Spring AOP 的关键词还有切点、通知、织入——@Around 怎么圈住目标方法、一个切面类怎么被翻译成代理逻辑,下一篇拆。

☕
503

10 年全栈工程师 · 503咖啡馆主理人

#Spring#AOP#动态代理#CGLIB#Spring Boot

评论 (0)

热门推荐

连载中 11/22

主从搭建实操:从零配出一主两从

光讲原理不过瘾?手把手搭一主两从:my.cnf 六个参数、复制账号、GTID、CHANGE REPLICATION SOURCE TO、SHOW REPLICA STATUS 验收,附翻车排查清单。

#MySQL#主从复制#GTID#主从搭建#高可用
2026-05-07 · 10136 阅读 · 0 评论 · 0 赞
连载中 16/22

连接池:HikariCP 参数与连接风暴

连接池不是越大越好:8 核机器配 1000 连接反而更慢的数学原理,HikariCP 四个必调参数,maxLifetime 与 wait_timeout 的隐形陷阱。

#MySQL#连接池#HikariCP#maxLifetime#连接风暴
2026-05-10 · 9900 阅读 · 0 评论 · 0 赞
连载中 4/16

缓存穿透:恶意 ID 打穿 MySQL 的四道防线

请求的数据在缓存和数据库里都不存在时,缓存形同虚设。聊聊参数校验、空值缓存、布隆过滤器、限流熔断四道防线的原理与组合打法。

#Redis#缓存穿透#布隆过滤器#高可用
2026-05-16 · 9330 阅读 · 21 评论 · 287 赞