Java-Proxy是在什么时候调用InvocationHandler的invoke方法的

最近看到spring的动态代理,扒到深处看到时 Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);看到这一句,顿时比较懵逼,还是没有搞懂invoke方法的调用,然后搜索了一下,碍,遇见一位大神的文章

特来记录一下,嘿嘿:首先这里是原文链接

其实前面的可以省略了(太晚啦,要睡觉啦),什么创建接口、实现类、创建实现InvocationHandler的类(不创建也行)等等操作,直接上重点,代理对象执行invoke的地方:

首先,我们编译后,会得出一个代理对象的class文件,打开这个class文件就解开谜题了(当时也是懵逼了,这招没想到,啊哈哈):

我们Proxy的类中,有一个受保护的InvocationHandler成员属性:

public class Proxy implements java.io.Serializable {

    private static final long serialVersionUID = -2222568056686623797L;

    /** parameter types of a proxy class constructor */
    private static final Class<?>[] constructorParams =
        { InvocationHandler.class };

    /**
     * a cache of proxy classes
     */
    private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

    /**
     * the invocation handler for this proxy instance.
     * @serial
     */
    protected InvocationHandler h;//在这里!

    /**
     * Prohibits instantiation.
     */
    private Proxy() {
    }

    /**
     * Constructs a new {@code Proxy} instance from a subclass
     * (typically, a dynamic proxy class) with the specified value
     * for its invocation handler.
     *
     * @param  h the invocation handler for this proxy instance
     *
     * @throws NullPointerException if the given invocation handler, {@code h},
     *         is {@code null}.
     */
    protected Proxy(InvocationHandler h) {
        Objects.requireNonNull(h);
        this.h = h;
    }

接着看代理对象的实现:

public final class $Proxy0 extends Proxy implements Subject(目标类,被代理的类) {
    private static Method m1;
    private static Method m0;
    private static Method m3;
    private static Method m2;  

    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("***.RealSubject").getMethod("request",  //代理方法名称
                    new Class[0]);  

            m2 = Class.forName("java.lang.Object").getMethod("toString",
                    new Class[0]);  

        } catch (NoSuchMethodException nosuchmethodexception) {
            throw new NoSuchMethodError(nosuchmethodexception.getMessage());
        } catch (ClassNotFoundException classnotfoundexception) {
            throw new NoClassDefFoundError(classnotfoundexception.getMessage());
        }
    } //static  

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

    @Override
    public final boolean equals(Object obj) {
        try {
            return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })) .booleanValue();
        } catch (Throwable throwable) {
            throw new UndeclaredThrowableException(throwable);
        }
    }  

    @Override
    public final int hashCode() {
        try {
            return ((Integer) super.h.invoke(this, m0, null)).intValue();
        } catch (Throwable throwable) {
            throw new UndeclaredThrowableException(throwable);
        }
    }  

    public final void request() {  //代理方法
        try {
            super.h.invoke(this, m3, null);
            return;
        } catch (Error e) {
        } catch (Throwable throwable) {
            throw new UndeclaredThrowableException(throwable);
        }
    }  

    @Override
    public final String toString() {
        try {
            return (String) super.h.invoke(this, m2, null);
        } catch (Throwable throwable) {
            throw new UndeclaredThrowableException(throwable);
        }
    }
}  

看到这里就明白了。新返回的代理对象,调用了父类(Proxy)h的方法,这里也就是invoke方法与Proxy相关的地方啦。

原文地址:https://www.cnblogs.com/cunkouzh/p/8620781.html

时间: 2024-10-17 14:49:34

Java-Proxy是在什么时候调用InvocationHandler的invoke方法的的相关文章

java.lang.reflect.InvocationHandler中invoke()方法调用时机

Java中动态代理的实现,关键就是这两个东西:Proxy.InvocationHandler,下面从InvocationHandler接口中的invoke方法入手,简单说明一下Java如何实现动态代理的. invoke方法的完整形式如下: public Object invoke(Object proxy, Method method, Object[] args) throws Throwable       {              method.invoke(obj, args);  

InvocationHandler中invoke()方法的调用问题

转InvocationHandler中invoke()方法的调用问题 Java中动态代理的实现,关键就是这两个东西:Proxy.InvocationHandler,下面从InvocationHandler接口中的invoke方法入手,简单说明一下Java如何实现动态代理的.         首先,invoke方法的完整形式如下: public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

java动态代理中的invoke方法是如何被自动调用的

转载:http://www.shangxueba.com/jingyan/1853835.html 一.动态代理与静态代理的区别.(1)Proxy类的代码被固定下来,不会因为业务的逐渐庞大而庞大:(2)可以实现AOP编程,这是静态代理无法实现的:(3)解耦,如果用在web业务下,可以实现数据层和业务层的分离.(4)动态代理的优势就是实现无侵入式的代码扩展. 静态代理这个模式本身有个大问题,如果类方法数量越来越多的时候,代理类的代码量是十分庞大的.所以引入动态代理来解决此类问题 二.动态代理 Ja

java Proxy(代理机制)

我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习的是其底层是怎么样的一个原理,而AOP的原理就是java的动态代理机制,所以本篇随笔就是对java的动态机制进行一个回顾. 在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Class),这一个类和接口是实现我

深入理解Java Proxy机制

动态代理其实就是java.lang.reflect.Proxy类动态的根据您指定的所有接口生成一个class byte,该class会继承Proxy类,并实现所有你指定的接口(您在参数中传入的接口数组):然后再利用您指定的classloader将 class byte加载进系统,最后生成这样一个类的对象,并初始化该对象的一些值,如invocationHandler,以即所有的接口对应的Method成员. 初始化之后将对象返回给调用的客户端.这样客户端拿到的就是一个实现你所有的接口的Proxy对象

[转]深入理解Java Proxy机制

该文章转自网络,原文不可考,给出转载文章链接:http://blog.csdn.net/rokii/article/details/4046098 看项目代码看到一段写的很美的代理机制,整理一下: 动态代理其实就是java.lang.reflect.Proxy类动态的根据您指定的所有接口生成一个class byte,该class会继承Proxy类,并实现所有你指定的接口(您在参数中传入的接口数组):然后再利用您指定的classloader将 class byte加载进系统,最后生成这样一个类的对

原!! java直接打印一个对象时,并不是直接调用该类的toString方法 ,而是会先判断是否为null,非null才会调用toString方法

网上看了好多java直接打印一个对象时,直接调用该类的toString方法 . 但是: Object obj=null; System.out.println(obj);//没有报错 System.out.println(obj.toString());//报空指针异常 System.out.println(obj);既然也是直接调用toString方法,为什么不报错??? 原因总结如下: 1.调用Object类的toString方法,必须保证object不是null值,否则将抛出NullPoi

使用Java的反射功能调用类中的方法

最近一直在搞Java的反射,今天使用反射调用方法时出现了很多问题,主要是没有详细参考官方API.所以走了很多弯路. 所以想把这个例子记下来,供自己也供他人学习. package com.mine.practice.reflect; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * 使用反射调用类中的方法 * @author 2014-11-5 上午10:51:28

JAVA深入研究——Method的Invoke方法。

在写代码的时候,发现从父类class通过getDeclaredMethod获取的Method可以调用子类的对象,而子类改写了这个方法,从子类class通过getDeclaredMethod也能获取到Method,这时去调用父类的对象也会报错.虽然这是很符合多态的现象,也符合java的动态绑定规范,但还是想弄懂java是如何实现的,就学习了下Method的源代码. Method的invoke方法 1.先检查 AccessibleObject的override属性是否为true. Accessibl