Java中的代理方式主要分为两种,一种是基于接口的动态代理,另一种是基于类的动态代理,而基于接口的动态代理有JDK Proxy,基于类的动态代理主要有ASM、cglib,本文主要讲述的是JDK Proxy实现动态代理。
JDK动态代理基于拦截器和反射实现,使用JDK代理时需要传入被代理类的class。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author Liutx
* @date 2021/3/6 10:57
* @Description 使用JDK的动态代理方式
*/
public class MyDynamicProxy {
public static void main(String[] args) {
HelloImpl hello = new HelloImpl();
MyInvocationHandler handler = new MyInvocationHandler(hello);
// 构造代码实例
Hello proxyHello = (Hello) Proxy.newProxyInstance(HelloImpl.class.getClassLoader(), HelloImpl.class.getInterfaces(), handler);
// 调用代理方法
proxyHello.sayHello();
}
}
interface Hello {
void sayHello();
}
class HelloImpl implements Hello {
@Override
public void sayHello() {
//原方法逻辑
System.out.println("Hello World");
}
}
/**
* 使用JDK Proxy代理为应用插入额外的逻辑
*/
class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("------插入前置通知代码-------------");
// 执行相应的目标方法
Object rs = method.invoke(target, args);
System.out.println("------插入后置处理代码-------------");
return rs;
}
}
JDK 动态代理是基于接口实现的代理操作,如果该类没有需要实现的接口则无法使用JDK代理,由于JDK的动态代理无需引入第三方的包,所以,在个人看来这既是JDK动态代理的优势又是其短板,在我们企业级开发常用的Spring框架中,经常使用到的Spring AOP技术使用了两种代理模式:JDK代理和cglib动态代理。
引用一下以下文字:
If the target class implements one or more interfaces, then Spring will create a JDK dynamic proxy that implements every interface. If the target class implements no interfaces, Spring will use CGLIB to create a new class on the fly that is a subclass (“extends”) the target class. This leads to one important difference: a JDK dynamic proxy cannot be casted to the original target class because it’s simply a dynamic proxy that happens to implement the same interface(s) as the target. This has the effect of “nudging” you to program to interfaces if they’re being used in your application’s model, since proxies will usually be invoked through those interfaces 如果被调用者没有实现接口,而我们还是希望利用动态代理机制,那么可以考虑其他方式。我们知道 Spring AOP 支持两种模式的动态代理,JDK Proxy 或者 cglib,如果我们选择 cglib 方式,你会发现对接口的依赖被克服了。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有