java动态代理的jdk和cjlib
时间: 2023-04-26 11:04:23 浏览: 108
Java动态代理是一种在运行时动态生成代理类的机制,它可以在不修改原始类的情况下,为其生成一个代理类,从而实现对原始类的增强或拦截。在Java中,有两种动态代理实现方式:JDK动态代理和CGLIB动态代理。
JDK动态代理是Java自带的一种动态代理实现方式,它是基于接口的代理,只能代理实现了接口的类。JDK动态代理通过反射机制在运行时动态生成代理类,代理类实现了被代理接口中的所有方法,并在方法调用时将请求转发给被代理对象。
CGLIB动态代理是一种基于继承的代理,它可以代理没有实现接口的类。CGLIB动态代理通过生成被代理类的子类来实现代理,代理类继承了被代理类,并重写了其中的方法,在方法调用时将请求转发给被代理对象。
总的来说,JDK动态代理适用于代理接口的情况,而CGLIB动态代理适用于代理类的情况。两种动态代理实现方式各有优缺点,具体使用哪种方式取决于具体的业务需求。
相关问题
java动态代理的jdk和cjlib的简单实例
Java动态代理是一种在运行时动态生成代理对象的技术。它可以代理某个接口或者类,使得代理对象可以拦截到对被代理对象的方法调用,并在调用前后进行一些额外的操作,比如记录日志、权限控制等。
Java提供了两种动态代理的实现方式:基于JDK的动态代理和基于CGLIB的动态代理。其中,基于JDK的动态代理只能代理实现了接口的类,而基于CGLIB的动态代理则可以代理任何类,包括没有实现接口的类。
下面是一个基于JDK的动态代理的简单实例:
```java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface Hello {
void sayHello();
}
class HelloImpl implements Hello {
public void sayHello() {
System.out.println("Hello, world!");
}
}
class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before invoking " + method.getName());
Object result = method.invoke(target, args);
System.out.println("After invoking " + method.getName());
return result;
}
}
public class Main {
public static void main(String[] args) {
Hello hello = new HelloImpl();
InvocationHandler handler = new MyInvocationHandler(hello);
Hello proxy = (Hello) Proxy.newProxyInstance(
Main.class.getClassLoader(),
new Class[] { Hello.class },
handler);
proxy.sayHello();
}
}
```
这里定义了一个接口`Hello`和它的实现类`HelloImpl`。`MyInvocationHandler`是一个实现了`InvocationHandler`接口的类,它负责拦截并处理对`Hello`接口的方法调用。`Main`类中创建了一个`HelloImpl`对象和一个`MyInvocationHandler`对象,然后调用`Proxy.newProxyInstance`方法构造一个代理对象。通过代理对象调用`sayHello`方法时,`MyInvocationHandler`会先打印一行`Before invoking sayHello`,然后再调用`HelloImpl`对象的`sayHello`方法,最后打印一行`After invoking sayHello`。
下面是一个基于CGLIB的动态代理的简单实例:
```java
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
class Hello {
public void sayHello() {
System.out.println("Hello, world!");
}
}
class MyMethodInterceptor implements MethodInterceptor {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("Before invoking " + method.getName());
Object result = proxy.invokeSuper(obj, args);
System.out.println("After invoking " + method.getName());
return result;
}
}
public class Main {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Hello.class);
enhancer.setCallback(new MyMethodInterceptor());
Hello hello = (Hello) enhancer.create();
hello.sayHello();
}
}
```
这里定义了一个类`Hello`和它的一个方法`sayHello`。`MyMethodInterceptor`是一个实现了`MethodInterceptor`接口的类,它负责拦截并处理对`Hello`类的方法调用。`Main`类中创建了一个`Enhancer`对象,通过`setSuperclass`方法指定要代理的类,通过`setCallback`方法指定拦截器,然后调用`create`方法构造一个代理对象。通过代理对象调用`sayHello`方法时,`MyMethodInterceptor`会先打印一行`Before invoking sayHello`,然后再调用`Hello`对象的`sayHello`方法,最后打印一行`After invoking sayHello`。
jdk和cjlib动态代理区别
JDK动态代理和CGLIB动态代理是两种常见的Java动态代理技术,它们在实现原理和应用场景上有一些区别。
JDK动态代理是通过Java的反射机制来实现的。它要求目标类必须实现一个或多个接口,代理类在运行时通过反射生成,对目标类的方法进行拦截并在拦截方法前后添加额外逻辑。JDK动态代理只能代理实现了接口的类,不支持对类的直接代理。
CGLIB动态代理则是通过继承目标类并重写其方法来实现的。它不要求目标类实现接口,通过生成目标类的子类,在子类中对目标方法进行拦截并添加额外逻辑。CGLIB动态代理可以代理没有实现接口的类,但对于final修饰的方法无法进行代理。
总结起来,JDK动态代理适用于对接口进行代理的场景,而CGLIB动态代理适用于对类进行代理的场景。选择使用哪种动态代理方式取决于具体的业务需求和目标类的特性。