基于JDK的动态代理原理分析 jdk动态代理底层原理


基于JDK的动态代理原理分析 jdk动态代理底层原理

文章插图
这篇文章解决三个问题:
1.What 动态代理是什么
2.How 动态代理怎么用
3.Why 动态代理的原理


动态代理是什么?
动态代理是代理模式的一种具体实现,是指在程序运行期间,动态的生成目标对象的代理类(直接加载在内存中的字节码文件),实现对目标对象所有方法的增强 。通过这种方式,我们可以在不改变(或无法改变)目标对象源码的情况下,对目标对象的方法执行前后进行干预 。
动态代理怎么用?
首先,准备好我们需要代理的类和接口,因为JDK的动态代理是基于接口实现的,所以被代理的对象必须要有接口
/*** SaySomething接口*/public interface SaySomething {public void sayHello();public void sayBye();}
/*** SaySomething的实现类*/public class SaySomethingImpl implements SaySomething {@Overridepublic void sayHello() {System.out.println("Hello World");}@Overridepublic void sayBye() {System.out.println("Bye Bye");}}
按照动态代理的用法,需要自定义一个处理器,用来编写自定义逻辑,实现对被代理对象的增强 。
自定义的处理器需要满足以下要求:
  • 需要实现InvocationHandler,重写invoke方法,在invoke方法中通过加入自定义逻辑,实现对目标对象的增强 。
  • 需要持有一个成员变量,成员变量的是被代理对象的实例,通过构造参数传入 。(用来支持反射调用被代理对象的方法)
  • 需要提供一个参数为被代理对象接口类的有参构造 。(用来支持反射调用被代理对象的方法)
/*** 自定义的处理器,用来编写自定义逻辑,实现对被代理对象的增强*/public class CustomHandler implements InvocationHandler {//需要有一个成员变量,成员变量为被代理对象,通过构造参数传入,用来支持方法的反射调用 。private SaySomething obj;//需要有一个有参构造,通过构造函数将被代理对象的实例传入,用来支持方法的反射调用public CustomHandler(SaySomething obj) {this.obj = obj;}/*** proxy:动态生成的代理类对象com.sun.proxy.$Proxy0* method:被代理对象的真实的方法的Method对象* args:调用方法时的入参*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//目标方法执行前的自定义逻辑处理System.out.println("-----before------");//执行目标对象的方法,使用反射来执行方法,反射需要传入目标对象,此时用到了成员变量obj 。Object result = method.invoke(obj, args);//目标方法执行后的自定义逻辑处理System.out.println("-----after------");return result;}}
这样我们就完成了自定义处理器的编写,同时在invoke方法中实现对了代理对象方法的增强,被代理类的所有方法的执行都会执行我们自定义的逻辑 。
接下来,需要通过Proxy,newProxyInstance()方法来生成代理对象的实例,并进行方法调用测试 。
public class JdkProxyTest {public static void main(String[] args) {//将生成的代理对象的字节码文件 保存到硬盘System.getProperties().setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");//被代理对象的实例SaySomething obj = new SaySomethingImpl();//通过构造函数,传入被代理对象的实例,生成处理器的实例InvocationHandler handler = new CustomHandler(obj);//通过Proxy.newProxyInstance方法,传入被代理对象Class对象、处理器实例,生成代理对象实例SaySomething proxyInstance = (SaySomething) Proxy.newProxyInstance(obj.getClass().getClassLoader(),new Class[]{SaySomething.class}, handler);//调用生成的代理对象的sayHello方法proxyInstance.sayHello();System.out.println("===================分割线==================");//调用生成的代理对象的sayBye方法proxyInstance.sayBye();}}


以上关于本文的内容,仅作参考!温馨提示:如遇健康、疾病相关的问题,请您及时就医或请专业人士给予相关指导!

「四川龙网」www.sichuanlong.com小编还为您精选了以下内容,希望对您有所帮助: