jdk动态代理实现原理总结

痛定思痛。 2021-11-26 10:46 404阅读 0赞

运行时创建一个代理对象的步骤为

  1. 生成代理类的字节码
  2. 加载字节码,创建代理对象

首先,代理对象的目的是在被调用方法的时候既能实现被代理对象的方法,又能够增加自己想要执行的方法,自然要获得被代理对象

代理类需要实现被代理对象的类的接口,因此生成的代理对象可以调用被代理对象所执行的方法。因此,创建代理类需要获得被代理对象的类的接口(反射获得)

代理类实现的接口方法由用户自定义放到一个类方法里,因此代理类需要拿到这个用户自定义的类(构造方法或者set方法)

既然要加载字节码,肯定要获得classLoader,可以由被代理对象从反射获得。

因此生成代理对象的方法为

//target为代理对象

  1. public <T> T getProxy() {
  2. return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),//类加载器,用于加载生成的代理类字节码
  3.     target.getClass().getInterfaces(), //代理类需要实现被代理对象的类的接口
  4.      this//用户自定义的代理方法的实现
  5. );
  6. }
  7. 以上为下面完整实现代码的截取 完整动态代理实现例子如下:
  8. 摘自

JDK动态代理实现原理

  1. package com.lnjecit.proxy;
  2. /**
  3. * Subject
  4. * 抽象主题接口
  5. * @author
  6. * @create 2018-03-29 14:16
  7. **/
  8. public interface Subject {
  9. void doSomething();
  10. }

复制代码

然后为接口RealSubject新建一个实现类RealSubject

复制代码

  1. /**
  2. * RealSubject
  3. * 真实主题类
  4. * @author
  5. * @create 2018-03-29 14:21
  6. **/
  7. public class RealSubject implements Subject {
  8. @Override
  9. public void doSomething() {
  10. System.out.println("RealSubject do something");
  11. }
  12. }

复制代码

接着创建一个代理类JDKDynamicProxy实现java.lang.reflect.InvocationHandler接口,重写invoke方法

复制代码

  1. package com.lnjecit.proxy.dynamic.jdk;
  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;
  4. import java.lang.reflect.Proxy;
  5. /**
  6. * JDKDynamicProxy
  7. * jdkd动态代理
  8. *
  9. * @author
  10. * @create 2018-03-29 16:17
  11. **/
  12. public class JDKDynamicProxy implements InvocationHandler {
  13. private Object target;
  14. public JDKDynamicProxy(Object target) {
  15. this.target = target;
  16. }
  17. /**
  18. * 获取被代理接口实例对象
  19. * @param <T>
  20. * @return
  21. */
  22. public <T> T getProxy() {
  23. return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
  24. }
  25. @Override
  26. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  27. System.out.println("Do something before");
  28. Object result = method.invoke(target, args);
  29. System.out.println("Do something after");
  30. return result;
  31. }
  32. }

复制代码

新建测试类Client测试结果

复制代码

  1. package com.lnjecit.proxy;
  2. import com.lnjecit.proxy.dynamic.jdk.JDKDynamicProxy;
  3. /**
  4. * Client
  5. * client测试代码
  6. *
  7. * @author
  8. * @create 2018-03-29 14:26
  9. **/
  10. public class Client {
  11. public static void main(String[] args) {
  12. // 保存生成的代理类的字节码文件
  13. System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
  14. // jdk动态代理测试
  15. Subject subject = new JDKDynamicProxy(new RealSubject()).getProxy();
  16. subject.doSomething();
  17. }
  18. }

复制代码

输出结果:

Do something before
RealSubject do something
Do something after

转载于:https://www.cnblogs.com/cai-cai777/p/11210721.html

发表评论

表情:
评论列表 (有 0 条评论,404人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JDK动态代理实现原理

    之前虽然会用JDK的动态代理,但是有些问题却一直没有搞明白。比如说:InvocationHandler的invoke方法是由谁来调用的,代理对象是怎么生成的,直到前几个星期才把

    相关 jdk动态代理实现原理

    jdk动态代理实际上是jvm帮我们建成的类实现我们传入的接口,加载字节码到jvm。实际上就是帮我们拼接的字符串和我们传进去的接口进行拼接,然后生成字节码加载进虚拟机。代理类持有

    相关 jdk动态代理实现原理总结

    运行时创建一个代理对象的步骤为 1. 生成代理类的字节码 2. 加载字节码,创建代理对象 首先,代理对象的目的是在被调用方法的时候既能实现被代理对象的方法,又能够增加自