jdk动态代理实现原理总结
Posted cai-cai777
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jdk动态代理实现原理总结相关的知识,希望对你有一定的参考价值。
运行时创建一个代理对象的步骤为
- 生成代理类的字节码
- 加载字节码,创建代理对象
首先,代理对象的目的是在被调用方法的时候既能实现被代理对象的方法,又能够增加自己想要执行的方法,自然要获得被代理对象
代理类需要实现被代理对象的类的接口,因此生成的代理对象可以调用被代理对象所执行的方法。因此,创建代理类需要获得被代理对象的类的接口(反射获得)
代理类实现的接口方法由用户自定义放到一个类方法里,因此代理类需要拿到这个用户自定义的类(构造方法或者set方法)
既然要加载字节码,肯定要获得classLoader,可以由被代理对象从反射获得。
因此生成代理对象的方法为
//target为代理对象
public <T> T getProxy() return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),//类加载器,用于加载生成的代理类字节码
target.getClass().getInterfaces(), //代理类需要实现被代理对象的类的接口
this//用户自定义的代理方法的实现
);
以上为下面完整实现代码的截取 完整动态代理实现例子如下:
摘自
JDK动态代理实现原理
package com.lnjecit.proxy; /** * Subject * 抽象主题接口 * @author * @create 2018-03-29 14:16 **/ public interface Subject void doSomething();
然后为接口RealSubject新建一个实现类RealSubject
/** * RealSubject * 真实主题类 * @author * @create 2018-03-29 14:21 **/ public class RealSubject implements Subject @Override public void doSomething() System.out.println("RealSubject do something");
接着创建一个代理类JDKDynamicProxy实现java.lang.reflect.InvocationHandler接口,重写invoke方法
package com.lnjecit.proxy.dynamic.jdk; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * JDKDynamicProxy * jdkd动态代理 * * @author * @create 2018-03-29 16:17 **/ public class JDKDynamicProxy implements InvocationHandler private Object target; public JDKDynamicProxy(Object target) this.target = target; /** * 获取被代理接口实例对象 * @param <T> * @return */ public <T> T getProxy() return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable System.out.println("Do something before"); Object result = method.invoke(target, args); System.out.println("Do something after"); return result;
新建测试类Client测试结果
package com.lnjecit.proxy; import com.lnjecit.proxy.dynamic.jdk.JDKDynamicProxy; /** * Client * client测试代码 * * @author * @create 2018-03-29 14:26 **/ public class Client public static void main(String[] args) // 保存生成的代理类的字节码文件 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); // jdk动态代理测试 Subject subject = new JDKDynamicProxy(new RealSubject()).getProxy(); subject.doSomething();
输出结果:
Do something before
RealSubject do something
Do something after
以上是关于jdk动态代理实现原理总结的主要内容,如果未能解决你的问题,请参考以下文章