jdk和cglib动态代理
时间: 2023-09-03 10:14:16 浏览: 147
JDK动态代理和CGLIB动态代理都是Java中常用的实现动态代理的方式。
JDK动态代理是Java提供的一种基于接口的动态代理机制。它通过在运行时创建一个实现指定接口的代理类对象来实现动态代理。JDK动态代理要求被代理的目标类必须实现一个或多个接口,并且代理类和目标类之间的关系是基于接口的。
CGLIB动态代理是基于字节码生成库ASM实现的,它通过生成目标类的子类来实现动态代理。相比JDK动态代理,CGLIB动态代理不要求目标类必须实现接口,因此可以代理没有实现接口的类。
在使用上,JDK动态代理使用java.lang.reflect.Proxy类来创建代理对象,而CGLIB动态代理使用net.sf.cglib.proxy.Enhancer类来生成代理子类。
总结来说,JDK动态代理适用于对接口进行代理的场景,而CGLIB动态代理适用于对类进行代理的场景。根据具体的需求和场景,可以选择适合自己的动态代理方式。
相关问题
jdk和cglib动态代理区别
JDK动态代理和CGLIB动态代理都是实现动态代理的技术,但它们的实现方式有所不同。
JDK动态代理是基于接口的代理,它要求被代理类实现一个接口,并通过反射机制来生成代理对象。因为JDK动态代理是基于接口的,所以只能代理实现了接口的类,不能代理没有实现接口的类。JDK动态代理在生成代理对象时,需要通过反射调用被代理类的方法,因此对于频繁调用的方法,JDK动态代理的性能较差。
CGLIB动态代理则是基于继承的代理,它不要求被代理类实现接口,而是通过继承被代理类来生成代理对象。CGLIB动态代理在生成代理对象时,会在内存中构建一个被代理类的子类,因此对于频繁调用的方法,CGLIB动态代理的性能较好。
需要注意的是,由于CGLIB动态代理是基于继承的,因此无法代理final方法和final类。此外,CGLIB动态代理在生成代理对象时,需要调用被代理类的构造方法,因此被代理类需要有一个无参的构造方法。
jdk和cglib动态代理的区别
### 比较JDK动态代理和CGLIB动态代理
#### 实现原理
JDK动态代理主要依赖于`java.lang.reflect.Proxy`类以及`InvocationHandler`接口来实现代理功能。通过这种方式,可以在运行时为一组接口创建代理实例,并且能够拦截这些接口的方法调用[^1]。
对于CGLIB动态代理而言,则是利用ASM字节码框架,在内存中实时生成目标类的子类,并重写其中的方法以达到增强业务逻辑的目的。由于采用的是继承的方式,因此被代理的对象不需要实现任何接口也可以完成操作[^2]。
#### 性能特点
通常来说,JDK动态代理因为只涉及到了反射层面的操作,所以在大多数情况下其执行效率会高于CGLIB动态代理;但是当涉及到大量方法调用或者频繁创建销毁代理对象的时候,两者之间的差距可能会缩小甚至反转。另外值得注意的一点是,如果应用程序中有大量的final修饰符限定的方法存在的话,那么使用CGLIB将会受到一定限制,因为它无法覆盖此类成员函数[^3]。
#### 适用场景
- **JDK动态代理**
更适合用于那些已经定义好了服务契约(即接口)的应用程序组件之间通信的地方。只要所有的参与者都遵循相同的协议标准即可正常工作。此外,由于它不改变原有代码结构,所以维护起来相对容易一些。
- **CGLIB动态代理**
当面对没有提供公共接口的具体类型时显得尤为有用。比如某些第三方库中的核心实体类可能并没有给出相应的抽象层次供外部扩展。此时借助于CGLIB就可以绕过这个问题轻松解决问题。不过需要注意的是,该方案并不适用于最终(final)类型的处理。
```java
// 使用JDK动态代理的例子
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkProxyExample {
public static void main(String[] args) {
MyInterface target = new TargetClass();
InvocationHandler handler = (proxy, method, arguments) -> {
System.out.println("Before calling " + method.getName());
Object result = method.invoke(target, arguments);
System.out.println("After calling " + method.getName());
return result;
};
MyInterface proxyInstance = (MyInterface) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
new Class[]{MyInterface.class},
handler);
proxyInstance.someMethod();
}
}
interface MyInterface {void someMethod();}
class TargetClass implements MyInterface{public void someMethod(){}}
```
```java
// 使用CGLIB动态代理的例子
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxyExample {
public static void main(String[] args){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(TargetClassForCglib.class); // 设置父类
enhancer.setCallback(new MethodInterceptor(){
@Override
public Object intercept(Object obj, Method method,
Object[] args, MethodProxy proxy) throws Throwable{
System.out.println("Before calling "+method.getName());
Object result=proxy.invokeSuper(obj,args);
System.out.println("After calling "+method.getName());
return result;
}});
TargetClassForCglib cglibProxy=(TargetClassForCglib)enhancer.create();
cglibProxy.someMethod();
}
static class TargetClassForCglib{
public void someMethod(){}
}
}
```
阅读全文
相关推荐












