0 0

Java中代理(Proxy)的实现机制5

看TIJ的代理看得有点晕,其中有一段代码如下。(print是包装了下的System.out.println)

package TypeInfo;
// typeinfo/SimpleDynamicProxy23.java
// TIJ4 Chapter Typeinfo, Exercise 23, page 598
// Inside invoke() in SimpleDynamicProxy.java, try to print the proxy argument and explain
// what happens.
import java.lang.reflect.*;

interface Interface {
    void doSomething();
    void somethingElse(String arg);
}

class RealObject implements Interface {
    public void doSomething() { print("doSomething"); }
    public void somethingElse(String arg) {
        print("somethingElse " + arg);
    }
}

class DynamicProxyHandler implements InvocationHandler {
    private Object proxied;
    public DynamicProxyHandler(Object proxied) {
        this.proxied = proxied;
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        /* 
        * trying to print proxy leads to:
        * StackOverFlowError 
        * at AbstractStringBuilder.<init>(Unknown Source)
        * at StringBuilder.<init>(Unknown Source)
        * at DynamicProxyHandler.invoke(SimpleDynamicProxy23.java)
        * at $Proxy0.toString(Unknown Source)
        * at String.valueOf(Unknown Source)
        * at StrinbBuilcer.append(Unknown Source)
        * at DynamicProxyHandler.invoke(SimpleDynamicProxy23.java), etc,
        * probably due to infinite recursion because calls to toString()
        * are passed repeatedly back to this invoke method
        */
        // System.out.println("proxy: " + proxy); // error
        System.out.println("**** proxy: " + proxy.getClass() +
            ", method: " + method + ", args: " + args);
        if(args != null)
            for(Object arg : args)
                System.out.println("  " + args);
        return method.invoke(proxied, args);
    }
}

class SimpleDynamicProxy23 {
    public static void consumer(Interface iface) {
        iface.doSomething();
        iface.somethingElse("bonobo");
    }
    public static void main(String[] args) {
        RealObject real = new RealObject();
        consumer(real);
        // Insert a proxy and call again:
        Interface proxy = (Interface)Proxy.newProxyInstance(
            Interface.class.getClassLoader(),
            new Class[]{ Interface.class },
            new DynamicProxyHandler(real));
        consumer(proxy);        
    }
}

代码比较容易看懂,但是其中的内在机制就很隐晦。调试时发现,consumer中调用Interface的方法后程序流直接就跳入了invoke。这是由什么机制决定的?换言之,在consumer中对接口Interface的方法的调用是如何转交给DynamicProxyHandler的invoke方法的?
书中有一句话:“在invoke()内部,在代理上调用方法时需要格外当心,因为对接口的调用将被重定向为对代理的调用。”这句解释了注释掉的“// System.out.println(&quot;proxy: &quot; + proxy); // error”的错误是因为引起了无限递归(很空洞的解释,具体怎样引起?)invoke的第一个参数proxy是什么类型?
希望大家不吝赐教。3Q!

2013年6月21日 17:20

4个答案 按时间排序 按投票排序

0 0

采纳的答案

推荐你看下
http://hllvm.group.iteye.com/group/topic/36843

然后dump出代理类出来 然后观察

我这里给你一份我dump出的

package TypeInfo;

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

public final class $Proxy0 extends Proxy
  implements Interface
{
  private static Method m1;
  private static Method m0;
  private static Method m3;
  private static Method m4;
  private static Method m2;

  public final void doSomething()
  {
    try
    {
      this.h.invoke(this, m3, null);
      return;
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void somethingElse(String paramString)
  {
    try
    {
      this.h.invoke(this, m4, new Object[] { paramString });
      return;
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public $Proxy0(InvocationHandler paramInvocationHandler)
  {
    super(paramInvocationHandler);
  }

  public final int hashCode()
  {
    try
    {
      return ((Integer)this.h.invoke(this, m0, null)).intValue();
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final boolean equals(Object paramObject)
  {
    try
    {
      return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final String toString()
  {
    try
    {
      return ((String)this.h.invoke(this, m2, null));
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  static
  {
    try
    {
      m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
      m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
      m3 = Class.forName("TypeInfo.Interface").getMethod("doSomething", new Class[0]);
      m4 = Class.forName("TypeInfo.Interface").getMethod("somethingElse", new Class[] { Class.forName("java.lang.String") });
      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
      return;
    }
    catch (NoSuchMethodException localNoSuchMethodException)
    {
      throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
    }
    catch (ClassNotFoundException localClassNotFoundException)
    {
      throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
    }
  }
}

2013年6月21日 19:02
0 0

我写过一个博客文章:http://dz.sdut.edu.cn/blog/subaochen/?p=232 简单解释了java动态代理的实现机制,希望能够帮到你。

2013年6月22日 14:44
0 0

调试时发现,consumer中调用Interface的方法后程序流直接就跳入了invoke。这是由什么机制决定的?
——————
Interface proxy = (Interface)Proxy.newProxyInstance( 
            Interface.class.getClassLoader(), 
            new Class[]{ Interface.class }, 
            new DynamicProxyHandler(real)); 
consumer(proxy);
这些代码决定的。
Proxy.newProxyInstance代码是JDK的代码,楼主是想了解JDK的底层实现...?
要了解这个, 就要了解JDK类字节码的生成, 了解了类字节码的生成就要了解类的加载器...

真没必要去纠结JDK的底层实现...如果想了解, 建议去看看《JAVA虚拟机》

2013年6月22日 09:25
0 0

坐等大牛解释,不过invoke的第一个参数proxy应该是被代理的一个实例,就是目标代理类,可以是一个接口的实现或者是一个类的子类...继续

2013年6月21日 17:56

相关推荐

    利用JAVA代理Proxy机制实现spring对ibaits的MapperScannerConfigurer功能

    利用JAVA代理Proxy机制实现spring对ibaits的MapperScannerConfigurer功能 详细:http://blog.csdn.net/wq105032007067/article/details/8812598

    Java动态代理实现 Proxy InvocationHandler

    总结来说,Java动态代理通过`Proxy`和`InvocationHandler`提供了灵活的代码扩展机制,可以在运行时为对象创建代理,实现在不修改原有代码的基础上添加额外功能。这在处理需要拦截和增强的对象时非常有用,例如日志...

    java Proxy 动态代理

    在Java中,动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类是用于创建一个代理对象,而InvocationHandler接口则定义了代理对象调用方法时的行为。 1. **...

    java proxy demo 代理类的运用demo

    在Java动态代理机制中,`Proxy`类是生成代理对象的工厂,而`InvocationHandler`接口定义了代理对象的方法调用处理逻辑。当我们创建一个代理对象时,需要提供一个实现了`InvocationHandler`接口的实例,这个实例将...

    Java 动态代理Proxy应用和底层源码分析.pdf

    ### Java 动态代理Proxy应用和底层源码分析 #### 一、Java动态代理简介 Java动态代理是一种在运行时动态生成代理类的技术,通过该技术可以为一个或多个接口生成一个实现类,该实现类可以拦截接口方法的调用,并...

    Java动态代理Proxy和cglib

    在Java编程中,动态代理是一种强大的机制,它允许我们在运行时创建对象的代理,以便在调用实际方法之前或之后添加额外的行为。本篇将详细探讨Java中的动态代理以及一个常用的第三方库Cglib。 首先,让我们从Java的...

    java动态代理机制

    在Java中,动态代理主要通过两个类来实现:`java.lang.reflect.Proxy` 和 `java.lang.reflect.InvocationHandler`。 1. **Proxy类**: `Proxy` 类是Java提供的一个内部类,它主要用于创建一个实现了指定一组接口的...

    Java中使用IE Proxy代理的方法

    本文将详细介绍如何在Java中使用IE Proxy代理来实现这一功能。 首先,我们需要理解Java中的网络访问机制。Java使用`java.net`包中的`Socket`和`HttpURLConnection`等类来处理网络通信。当程序运行时,它会使用系统...

    基于Java动态代理和反射机制实现ORM

    在Java中,基于动态代理和反射机制实现ORM可以提高代码的可维护性和灵活性。本篇文章将深入探讨如何在Java环境下,结合MySQL数据库,利用动态代理和反射技术来实现简单的ORM框架。 首先,我们需要了解动态代理和...

    proxy.rar java三种代理模式源码

    总结来说,"proxy.rar"压缩包提供了Java编程中三种代理模式的源代码实例,通过学习这些代码,开发者可以深入理解代理模式的原理和实现,同时掌握泛型在实际项目中的应用。对于提高代码的可扩展性和可维护性,这些都...

    Java动态代理两种实现方式

    总结来说,Java动态代理为开发者提供了灵活的代码扩展机制,可以根据实际需求选择适合的实现方式。JDK动态代理适用于接口丰富的场景,而Cglib更适合对性能有较高要求或者目标对象无法实现接口的情况。

    Java动态代理[动态类Proxy的使用]

    在Java编程中,动态代理是一种强大的机制,它允许我们在运行时创建代理类,这些代理类可以代表或增强原始目标类的行为。动态代理通常用于实现AOP(面向切面编程)或者提供诸如日志、事务管理等跨切面的功能。本文将...

    java proxy

    Java代理在编程中是一种强大的设计模式,主要用于在不修改原有对象的...总的来说,Java代理机制在日志记录、性能监控、事务管理等场景中都有广泛的应用,通过代理可以灵活地为对象添加额外的行为,而无需修改原始代码。

    代理模式java代码 Proxy(4)

    在Java中,代理模式可以通过多种方式实现,包括静态代理和动态代理。 在提供的文件列表中,我们可以看到以下几个关键类: 1. `ProxyDisplay`:这个名字暗示了它可能是代理模式中的代理类,用于代表或代替某个实际...

    深入理解Java Proxy机制.doc

    总结,Java Proxy机制是Java中一种强大的工具,它允许我们在运行时动态地创建代理类和对象,从而实现对方法调用的拦截和增强。通过结合`InvocationHandler`,我们可以灵活地添加额外的逻辑,实现AOP编程模式,提升...

    JAVA实现动态代理的简单流程

    在深入探讨Java动态代理的实现过程之前,我们首先需要理解动态代理的基本概念及其在Java中的应用价值。动态代理,顾名思义,是在运行时动态创建代理对象的一种机制,它无需在编译期就确定代理类的具体实现,而是通过...

    Java_ProxyServer.rar_Java ProxyServer_java proxy server

    在Java中实现ProxyServer,通常涉及到Socket编程、多线程以及网络协议的理解。 首先,ProxyServer的核心在于其`serve()`方法,这是处理客户端请求的关键。当客户端发起连接请求时,`serve()`会被调用,它创建一个新...

    httpProxy-java

    在Java中实现HTTP代理,通常涉及以下几个核心概念: 1. Socket编程:Java的Socket类提供了低级别的网络通信接口,可以用于建立TCP连接,是实现HTTP代理的基础。通过创建ServerSocket监听客户端连接,然后为每个连接...

    java动态代理模拟实现

    总结起来,Java动态代理提供了一种在运行时创建代理对象的机制,通过 `Proxy` 类和 `InvocationHandler` 接口,我们可以灵活地在方法调用前后插入自定义的行为,实现诸如日志、事务等附加功能,极大地增强了代码的可...

    代理模式java代码 Proxy(5) 2个代理类

    Java提供了动态代理机制,主要是通过`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`接口来实现。动态代理的优点是可以在运行时动态创建代理对象,不需要预先编写代理类。下面是一个动态代理的...

Global site tag (gtag.js) - Google Analytics