spring中用的什么动态代理
-
在Spring框架中,主要使用两种类型的动态代理:JDK动态代理和CGLIB动态代理。
-
JDK动态代理:
JDK动态代理是通过Java中的反射机制实现的。它要求目标对象必须实现一个或多个接口,并且代理类会实现这些接口,并且代理对象和目标对象具有相同的接口类型。在运行时,通过代理对象调用方法时,会经过一系列的代理处理,包括方法拦截、增强等操作,最终再调用目标对象的方法。JDK动态代理能够在运行时动态生成代理类,并将目标对象的方法调用转发到代理类中。JDK动态代理适用于有接口的情况。 -
CGLIB动态代理:
CGLIB动态代理是通过继承目标对象并重写其中的方法来实现的。它不要求目标对象必须实现接口,而是直接继承目标对象,生成一个子类作为代理类。在运行时,通过代理对象调用方法时,会直接调用代理类的方法,并在方法中通过回调机制来调用目标对象的方法。CGLIB动态代理能够在运行时动态生成代理类,并继承目标对象的所有非final方法。CGLIB动态代理适用于没有接口的情况。
总结:
在Spring中,根据目标对象是否实现了接口,可以选择使用JDK动态代理或CGLIB动态代理来生成代理对象。JDK动态代理适用于有接口的情况,而CGLIB动态代理适用于没有接口的情况。Spring框架会根据配置文件中的设置来自动选择使用哪种动态代理方式。1年前 -
-
在Spring框架中,用到了两种类型的动态代理:JDK动态代理和CGLib动态代理。
-
JDK动态代理:JDK动态代理是通过Java的反射机制实现的。它要求目标类实现一个或多个接口,并且代理类通过实现InvocationHandler接口来拦截目标类的方法调用。JDK动态代理的优势在于它是基于接口的代理,可以代理任意实现了接口的类,但是缺点是只能代理实现了接口的类,不能代理没有实现接口的类。
-
CGLib动态代理:CGLib动态代理是通过继承目标类的方式来实现的。它不要求目标类实现接口,而是通过创建目标类的子类,并重写其中的方法来实现代理。CGLib动态代理的优势在于它可以代理任意类,包括没有实现接口的类。但是缺点是由于代理类是目标类的子类,所以目标类的final方法无法被代理。
-
Spring AOP:Spring框架使用动态代理实现了面向切面编程(AOP)的功能。通过在配置文件中定义切点和通知,Spring框架可以在运行时动态地将切面逻辑织入到目标类的方法调用中,而不需要修改目标类的代码。Spring AOP默认使用JDK动态代理来实现代理功能,但是当目标类没有实现接口时,Spring AOP会自动切换为使用CGLib动态代理。
-
使用场景:JDK动态代理适用于需要代理接口的情况,例如使用动态代理实现事务管理、日志记录等功能。CGLib动态代理适用于没有接口或者需要代理类的情况,例如在无法修改目标类的情况下,对类进行增强或者拦截。
-
性能比较:由于JDK动态代理是基于接口的代理,所以它的性能比CGLib动态代理要好。而CGLib动态代理由于要继承目标类,所以在生成代理类的过程中需要更多的时间和内存,因此性能相对较差。但是由于CGLib动态代理是直接操作字节码,所以在方法调用过程中的性能要优于JDK动态代理。所以在选择动态代理实现方式时需要根据具体的场景来决定使用哪种方式。
1年前 -
-
在Spring框架中,主要使用了两种动态代理方式:JDK动态代理和CGLIB动态代理。
- JDK动态代理
JDK动态代理是基于Java反射机制实现的。它要求被代理的类必须实现一个接口,通过在运行时创建一个代理类来替代原始类。JDK动态代理主要使用了java.lang.reflect.Proxy和java.lang.reflect.InvocationHandler两个类。
下面是使用JDK动态代理的步骤:
- 定义接口:创建一个接口或者使用已有的接口,作为代理类和被代理类的公共接口。
- 实现InvocationHandler接口:自定义一个类实现InvocationHandler接口,并实现invoke方法,该方法中定义了对原始方法的增强逻辑。
- 创建代理对象:通过Proxy类的newProxyInstance方法创建代理对象。该方法需要传入三个参数:ClassLoader,被代理的接口数组,和实现了InvocationHandler接口的对象。
- 调用代理对象方法:通过代理对象调用方法,实际上会调用InvocationHandler中的invoke方法,在invoke方法内部实现对原方法的增强逻辑。
JDK动态代理的优点是能够在不侵入原始类的情况下实现代理,缺点是要求被代理的类必须实现接口。
- CGLIB动态代理
CGLIB动态代理是基于字节码操作实现的。它通过继承被代理类来生成代理类。CGLIB动态代理不要求被代理的类实现接口。
下面是使用CGLIB动态代理的步骤:
- 引入依赖:在项目的构建文件(比如pom.xml)中添加cglib的依赖。
- 创建Enhancer对象:通过CGLIB的Enhancer类创建一个代理对象,该类是CGLIB的主要入口。
- 设置被代理的类和回调方法:通过enhancer.setSuperclass和enhancer.setCallback方法设置被代理的类和回调方法,回调方法实现了对原始方法的增强逻辑。
- 创建代理对象:通过enhancer.create方法创建代理对象。
- 调用代理对象方法:通过代理对象调用方法,实际上会调用回调方法,在回调方法内部实现对原方法的增强逻辑。
CGLIB动态代理的优点是能够代理没有实现接口的类,缺点是生成的代理类不支持final方法和final类的代理。
总结:
在Spring中,JDK动态代理和CGLIB动态代理都有各自的使用场景。如果被代理的类已经实现了接口,可以选择使用JDK动态代理;如果被代理的类没有实现接口,可以选择使用CGLIB动态代理。在Spring AOP中,默认使用JDK动态代理实现代理功能,但是当需要代理的类没有实现接口时,Spring会自动切换到CGLIB动态代理。1年前 - JDK动态代理