JDK代理和CGLIB代理总结

本文详细介绍了在Spring框架中AOP(面向切面编程)的实现方式,包括JDK动态代理与CGLIB两种代理机制的选择及应用。通过具体代码示例展示了如何根据不同情况选择合适的代理类型,并解释了它们之间的主要区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
(如果就是单纯的用IOC生成一个对象,也没有AOP的切入不会生成代理的,只会NEW一个实例,给Spring的Bean工厂 )

2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP
如何强制使用CGLIB实现AOP
* 添加CGLIB库
* 在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class="true"/>就能强制使用

3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换(没有实现接口的就用CGLIB代理,使用了接口的类就用JDK动态代理)

 

 

JDK动态代理和CGLIB字节码生成的区别?
* JDK动态代理只能对实现了接口的类生成代理,而不能针对类

           Proxy.newProxyInstance(

                   target.getClass().getClassLoader(),

                   target.getClass().getInterfaces(),//要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)

                   this)
* CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法
  因为是继承,所以该类或方法最好不要声明成final

  1.     /**  
  2.      * 创建代理对象  
  3.      *   
  4.      * @param target  
  5.      * @return  
  6.      */  
  7.     public Object getInstance(Object target) {   
  8.         this.target = target;   
  9.         Enhancer enhancer = new Enhancer();   
  10.         enhancer.setSuperclass(this.target.getClass());   
  11.         // 回调方法   
  12.         enhancer.setCallback(this); 
  13.         // 创建代理对象   
  14.         return enhancer.create();   
  15.     }   
  16.   
  17.     @Override  
  18.     // 回调方法   
  19.     public Object intercept(Object obj, Method method, Object[] args,   
  20.             MethodProxy proxy) throws Throwable {   
  21.         System.out.println("事物开始");   
  22.         proxy.invokeSuper(obj, args);  //还是执行父类的方法
  23.       System.out.println("事物结束");   
  24.         return null;   
  25.     }   
<think>好的,我现在需要回答用户关于JDK代理Cglib代理区别的问题。首先,我要回忆这两个代理机制的基本概念应用场景。 JDK动态代理是基于接口的,我记得它使用Java的反射机制来生成代理对象。用户提到的Spring AOP默认在目标对象实现了接口时使用JDK代理。那它的实现方式是创建一个实现相同接口的代理类,然后通过InvocationHandler来处理方法调用。这点需要确认是否正确。 而Cglib代理则是通过字节码增强技术,生成目标类的子类来实现代理。它不需要目标对象实现接口,可以直接代理类。Spring在目标类没有实现接口时会使用Cglib。这里可能需要提到Cglib的底层库ASM,以及它如何操作字节码。 接下来要考虑两者的性能差异。传统观点认为Cglib在生成代理时速度较慢,但执行效率高,而JDK代理生成快但执行慢。不过,随着JDK版本的更新,这个差距可能已经缩小,需要核实最新的情况。 还有限制方面,JDK代理只能代理接口中的方法,无法代理没有接口的类。而Cglib不能代理final类或方法,因为子类无法覆盖这些方法。这点很重要,需要明确指出。 依赖关系方面,JDK代理是Java自带的,无需额外依赖,而Cglib需要引入第三方库。例如,Spring Core已经包含了Cglib,但如果项目中没有相关依赖,可能需要单独添加。 另外,要提到Spring Boot 2.x之后默认使用Cglib,即使有接口也优先使用Cglib,但可以通过配置切换回JDK代理。这可能是因为Cglib的功能更全面,或者为了统一代理方式。 需要检查是否有其他区别,比如代理对象的生成方式、内存占用、对构造函数的影响等。例如,Cglib会生成子类,所以代理对象会调用父类的构造函数,而JDK代理则是实现接口,不需要构造函数。 总结时,要分点列出两者的区别,包括实现原理、依赖、限制、性能使用场景。确保信息准确,避免过时的观点,比如性能对比部分需要根据最新JDK版本的情况调整。 最后,考虑用户可能的实际应用场景,例如在Spring项目中如何选择,或者遇到代理不生效时的排查点。例如,当使用JDK代理时,如果目标类没有接口,就会导致代理失败,而Cglib则可以处理这种情况。或者在配置AOP时,如何强制使用Cglib代理。 需要验证是否存在错误,例如Cglib是否真的不能代理final方法,以及JDK代理Cglib代理Spring中的默认行为是否如所述。可能还需要查阅Spring官方文档确认默认行为的变化,比如在Spring Boot 2.x之后的变化。 总之,回答需要结构清晰,分点说明,涵盖实现方式、使用条件、性能、依赖、限制适用场景,并给出实际示例或配置建议,帮助用户理解应用。</think>在Spring框架中,JDK动态代理CGLIB代理是实现AOP的两种核心技术,它们的核心区别如下: --- ### **一、实现原理对比** | | JDK动态代理 | CGLIB代理 | |------------------|----------------------------------------|-----------------------------------------| | **技术基础** | 基于接口(使用`java.lang.reflect.Proxy`) | 基于继承(通过ASM字节码增强生成子类) | | **代理目标** | **必须**实现至少一个接口 | 可代理**任意普通类**(无需实现接口) | | **代理方式** | 实现相同接口的代理类 | 生成目标类的子类 | --- ### **二、实现机制详解** #### 1. **JDK动态代理** - **代码示例**: ```java public class JdkProxyDemo { public static void main(String[] args) { TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance( ClassLoader.getSystemClassLoader(), new Class[]{TargetInterface.class}, (proxy, method, args1) -> { System.out.println("Before method"); return method.invoke(new TargetImpl(), args1); }); proxy.doSomething(); } } ``` - **关键特点**: - 代理类文件名格式:`$Proxy0`、`$Proxy1`... - 通过`InvocationHandler`实现方法拦截 - **无法代理**
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值