zoukankan      html  css  js  c++  java
  • JDK动态代理分析

    1. JDK动态代理分析

    代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。

    就jdk动态代理而言,代理的UML图如下

    这里又三个重要的角色

    • 接口:代理类和被代理类
    • 被代理类:真实业务处理的类
    • 代理类:由jdk动态代理生成的类,一般以$Prxoy0结尾

    2. 使用代码

    2.1 接口类

    public interface InterfaceObject {
        void sayhello();
    }
    

    2.2被代理类

    public class RealObject implements InterfaceObject{
        @Override
        public void sayhello() {
            System.out.println("say hello");
        }
    }
    

    2.3 调用处理器

    调用处理器优点类似于spring的aop功能,spring的aop也是基于动态代理实现的。

    public class ObjectInvocationHandler implements InvocationHandler {
        private Object subject;
    
        public ObjectInvocationHandler(Object subject) {
            this.subject = subject;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("在调用之前,我要干点啥呢?");
            Object returnValue = method.invoke(subject, args);
            System.out.println("在调用之后,我要干点啥呢?");
            return returnValue;
        }
    }
    

    2.4 运行方法

    public class Main {
        public static void main(String[] args) {
            //这里基于1.8,用于保存jdk动态生成的代理类
            System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
            RealObject realObject = new RealObject();
            ObjectInvocationHandler objectInvocationHandler = new ObjectInvocationHandler(realObject);
    
            ClassLoader loader = realObject.getClass().getClassLoader();
            Class[] interfaces = realObject.getClass().getInterfaces();
            //这里的功能其实很明显,就是为了获取最终的代理类,那么具体的逻辑就可以去看看代理类的执行逻辑了
            InterfaceObject interfaceObject = (InterfaceObject) Proxy.newProxyInstance(loader, interfaces, objectInvocationHandler);
            interfaceObject.sayhello();
        }
    }
    

    在运行时打断点查看返回的 interfaceObject的具体实现,可以看到这个类是

    3.源码分析

    1. 调用代理方法获取最终的代理类

      InterfaceObject interfaceObject = (InterfaceObject) Proxy.newProxyInstance(loader, interfaces, objectInvocationHandler);
      

      这句代码很关键,有兴趣的可以跟进去看一下,这里的主要目的是生成代理类

    2. 代理类分析(这里贴主要代码)

      //代理类实现了InterfaceObject
      public final class $Proxy0 extends Proxy implements InterfaceObject {
          //实现了接口的业务方法sayhello,最终运行调用的就是这个方法
      	public final void sayhello() throws  {
              try {
      		   //这里最终调用的其实就是我们的处理器方法
                  super.h.invoke(this, m3, (Object[])null);
              } catch (RuntimeException | Error var2) {
                  throw var2;
              } catch (Throwable var3) {
                  throw new UndeclaredThrowableException(var3);
              }
          }
          //这里可以看到m3就是我们的sayhello方法
          static {
              try {
                  m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
                  m2 = Class.forName("java.lang.Object").getMethod("toString");
                  m3 = Class.forName("com.hsm.java.proxy.jdk.InterfaceObject").getMethod("sayhello");
                  m0 = Class.forName("java.lang.Object").getMethod("hashCode");
              } catch (NoSuchMethodException var2) {
                  throw new NoSuchMethodError(var2.getMessage());
              } catch (ClassNotFoundException var3) {
                  throw new NoClassDefFoundError(var3.getMessage());
              }
          }
      }
      
  • 相关阅读:
    人生感悟经典名言大全
    Linux<DNS配置>
    CentOS7安装详细步骤
    8 个实用在线工具,破解工作学习中的80%难题!
    java.sql.SQLException: Access denied for user '@' localhost' (using password: NO)
    windows10系统激活的方法
    程序猿小哥哥教你们把自己网站变灰色,哀悼……
    常用正则表达式
    2020年Web前端最新框架技术
    Navicat Premium 15 永久激活版安装教程
  • 原文地址:https://www.cnblogs.com/steven158/p/15673101.html
Copyright © 2011-2022 走看看