栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

jdk动态代理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

jdk动态代理

  1. 什么是代理

    代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间,从而在设计上获得了更大的灵活性。

  2. 什么是动态代理

    在运行时生成的class。

    动态代理步骤:

    1. 创建一个实现接口InvocationHandler的类,它必须实现invoke方法

    2. 创建被代理的类以及接口

    3. 通过Proxy的静态方法 newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)创建一个代理

    4. 通过代理调用方法

  3. jdk的动态代理使用

    1. 需要动态代理的接口:

       
      public interface Subject
      {
          
          public String SayHello(String name);
       
          
          public String SayGoodBye();
      }

    2. 需要代理的实际对象

      public class RealSubject implements Subject
      {
       
          
          public String SayHello(String name)
          {
              return "hello " + name;
          }
       
          
          public String SayGoodBye()
          {
              return " good bye ";
          }
      }
    3. 调用处理器实现类(有木有感觉这里就是传说中的AOP啊)

      import java.lang.reflect.InvocationHandler;
      import java.lang.reflect.Method;
       
       
      
      public class InvocationHandlerImpl implements InvocationHandler
      {
       
          
          private Object subject;
       
          
          public InvocationHandlerImpl(Object subject)
          {
              this.subject = subject;
          }
       
          
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
          {
              //在代理真实对象前我们可以添加一些自己的操作
              System.out.println("在调用之前,我要干点啥呢?");
       
              System.out.println("Method:" + method);
       
              //当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
              Object returnValue = method.invoke(subject, args);
       
              //在代理真实对象后我们也可以添加一些自己的操作
              System.out.println("在调用之后,我要干点啥呢?");
       
              return returnValue;
          }
      }
    4. 测试

      import java.lang.reflect.InvocationHandler;
      import java.lang.reflect.Proxy;
       
      
      public class DynamicProxyDemonstration
      {
          public static void main(String[] args)
          {
              //代理的真实对象
              Subject realSubject = new RealSubject();
              
              
              InvocationHandler handler = new InvocationHandlerImpl(realSubject);
       
              ClassLoader loader = realSubject.getClass().getClassLoader();
              Class[] interfaces = realSubject.getClass().getInterfaces();
              
              Subject subject = (Subject) Proxy.newProxyInstance(loader, interfaces, handler);
       
              System.out.println("动态代理对象的类型:"+subject.getClass().getName());
       
              String hello = subject.SayHello("jiankunking");
              System.out.println(hello);
      //        String goodbye = subject.SayGoodBye();
      //        System.out.println(goodbye);
          }
       
      }

4. 动态代理实现

        动态生成代理类:         

         通过ProxyGenerator.generateProxyClass(name,new Class[]{Subject.class})查看生成的字节码:

import sun.misc.ProxyGenerator;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
 

public class DynamicProxyDemonstration
{
    public static void main(String[] args)
    {
        //代理的真实对象
        Subject realSubject = new RealSubject();
 
        
        InvocationHandler handler = new InvocationHandlerImpl(realSubject);
 
        ClassLoader loader = handler.getClass().getClassLoader();
        Class[] interfaces = realSubject.getClass().getInterfaces();
        
        Subject subject = (Subject) Proxy.newProxyInstance(loader, interfaces, handler);
 
        System.out.println("动态代理对象的类型:"+subject.getClass().getName());
 
        String hello = subject.SayHello("jiankunking");
        System.out.println(hello);
        // 将生成的字节码保存到本地,
        createProxyClassFile();
    }
    private static void createProxyClassFile(){
        String name = "ProxySubject";
        byte[] data = ProxyGenerator.generateProxyClass(name,new Class[]{Subject.class});
        FileOutputStream out =null;
        try {
            out = new FileOutputStream(name+".class");
            System.out.println((new File("hello")).getAbsolutePath());
            out.write(data);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(null!=out) try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
 
}

        用jd-jui 工具将生成的字节码反编译:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import jiankunking.Subject;
 
public final class ProxySubject
  extends Proxy
  implements Subject
{
  private static Method m1;
  private static Method m3;
  private static Method m4;
  private static Method m2;
  private static Method m0;
  
  public ProxySubject(InvocationHandler paramInvocationHandler)
  {
    super(paramInvocationHandler);
  }
  
  public final boolean equals(Object paramObject)
  {
    try
    {
      return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  public final String SayGoodBye()
  {
    try
    {
      return (String)this.h.invoke(this, m3, null);
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  public final String SayHello(String paramString)
  {
    try
    {
      return (String)this.h.invoke(this, m4, new Object[] { paramString });
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  public final String toString()
  {
    try
    {
      return (String)this.h.invoke(this, m2, null);
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  public final int hashCode()
  {
    try
    {
      return ((Integer)this.h.invoke(this, m0, null)).intValue();
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  static
  {
    try
    {
      m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
      m3 = Class.forName("jiankunking.Subject").getMethod("SayGoodBye", new Class[0]);
      m4 = Class.forName("jiankunking.Subject").getMethod("SayHello", new Class[] { Class.forName("java.lang.String") });
      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
      m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
      return;
    }
    catch (NoSuchMethodException localNoSuchMethodException)
    {
      throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
    }
    catch (ClassNotFoundException localClassNotFoundException)
    {
      throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
    }
  }
}

参考:Java JDK 动态代理(AOP)使用及实现原理分析

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/439509.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号