java 动态代理

本文深入探讨Java动态代理机制,对比静态代理,强调其灵活性及在未知原始类的情况下即可定义代理行为的特点。通过实例代码展示了如何实现动态代理,并解析了动态生成的代理类代码结构。

0x01 描述

”动态代理中的动态,是针对使用java代码实际编写了代理类的“静态”代理而言的,它的优势不在于省去了编写代理类的那一点工作量,而是实现了可以在原始类和接口还未知的时候,就可以确定代理类的行为,当代理类与原始类脱离直接联系后,就可以很灵活地重用于不同的应用场景中"  引自 《深入理解java虚拟机 java高级特性与最佳实践》。

它的缺点:因为java中类只支持单继承,而代理类有个共同的父类Proxy,所有注定了动态代理不能为类成员方法作代理的缺陷。

0x02 demo

package test;
public interface IWorker {
    Object work(Object... objects);
}
package test;

public class Worker implements IWorker {

    @Override
    public Object work(Object... objects) {
        System.out.println("Working ...");
        return "work method";
    }
}
package test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class Handler implements InvocationHandler {
    IWorker mWorker;

    Handler(IWorker iWorker) {
        this.mWorker = iWorker;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        if (method.getName().equals("equals")) {
            System.out.println("the equals method will always return true");
            return true;
        } else if (method.getName().equals("hashCode")) {
            System.out.println("yes, the hashCode is ");
        } else if (method.getName().equals("toString")) {
            System.out.println("toString method has been called");
        }
        return method.invoke(mWorker, args);
    }

}
package test;

import java.lang.reflect.Proxy;

public class Test {
    public static void main(String[] args) {
        System.getProperties().put(
                "sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        IWorker worker = (IWorker) Proxy.newProxyInstance(
                IWorker.class.getClassLoader(), Worker.class.getInterfaces(),
                new Handler(new Worker()));
        System.out.println(worker.work());
        System.out.println(worker.equals(null));
        System.out.println(worker.toString());
        System.out.println(worker.hashCode());
    }
}

0x03 动态生成的代理类的代码

package com.sun.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import test.IWorker;

public final class $Proxy0
  extends Proxy
  implements IWorker
{
  private static Method m1;
  private static Method m2;
  private static Method m3;
  private static Method m0;
  
  public $Proxy0(InvocationHandler paramInvocationHandler)
    throws 
  {
    super(paramInvocationHandler);
  }
  
  public final boolean equals(Object paramObject)
    throws 
  {
    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 toString()
    throws 
  {
    try
    {
      return (String)this.h.invoke(this, m2, null);
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  public final Object work(Object[] paramArrayOfObject)
    throws 
  {
    try
    {
      return (Object)this.h.invoke(this, m3, new Object[] { paramArrayOfObject });
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
  
  public final int hashCode()
    throws 
  {
    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") });
      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
      m3 = Class.forName("test.IWorker").getMethod("work", new Class[] { Class.forName("[Ljava.lang.Object;") });
      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());
    }
  }
}

 0x04 注意

1、动态生成的方法都是final的

2、除了接口中的方法外,默认它还覆盖了Object类中的toString、hashCode和equals方法

3、每个方法都进行了异常的捕捉,虽然对异常进行了简单的分类处理,但是仍然使用了奇怪的语法将捕捉到的运行时异常照常抛出,所以在使用到代理类的地方照样可以使用正常的异常出来逻辑来处理运行时抛出的异常

转载于:https://www.cnblogs.com/LuLei1990/p/4593737.html

标题基于SpringBoot的马术俱乐部管理系统设计与实现AI更换标题第1章引言介绍马术俱乐部管理系统的研究背景、意义、国内外研究现状、论文方法及创新点。1.1研究背景与意义阐述马术俱乐部管理系统对提升俱乐部管理效率的重要性。1.2国内外研究现状分析国内外马术俱乐部管理系统的发展现状及存在的问题。1.3研究方法以及创新点概述本文采用的研究方法,包括SpringBoot框架的应用,以及系统的创新点。第2章相关理论总结和评述与马术俱乐部管理系统相关的现有理论。2.1SpringBoot框架理论介绍SpringBoot框架的基本原理、特点及其在Web开发中的应用。2.2数据库设计理论阐述数据库设计的基本原则、方法以及在管理系统中的应用。2.3马术俱乐部管理理论概述马术俱乐部管理的基本理论,包括会员管理、课程安排等。第3章系统设计详细描述马术俱乐部管理系统的设计方案,包括架构设计、功能模块设计等。3.1系统架构设计给出系统的整体架构,包括前端、后端和数据库的交互方式。3.2功能模块设计详细介绍系统的各个功能模块,如会员管理、课程管理、预约管理等。3.3数据库设计阐述数据库的设计方案,包括表结构、字段设计以及数据关系。第4章系统实现介绍马术俱乐部管理系统的实现过程,包括开发环境、编码实现等。4.1开发环境搭建介绍系统开发所需的环境,包括操作系统、开发工具等。4.2编码实现详细介绍系统各个功能模块的编码实现过程。4.3系统测试与调试阐述系统的测试方法、测试用例以及调试过程。第5章系统应用与分析呈现马术俱乐部管理系统的应用效果,并进行性能分析。5.1系统应用情况介绍系统在马术俱乐部中的实际应用情况。5.2系统性能分析从响应时间、并发处理能力等方面对系统性能进行分析。5.3用户反馈与改进收集用户反馈,提出系统改进建议。第6章结论与展望总结马术俱乐部管理系统的设计与实现成果,并展望未来的研究
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值