java Proxy InvocationHandler 动态代理实现详解

Posted dyfbk

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java Proxy InvocationHandler 动态代理实现详解相关的知识,希望对你有一定的参考价值。

  spring 两大思想,其一是IOC,其二就是AOP..而AOP的原理就是java 的动态代理机制。这里主要记录java 动态代理的实现及相关类的说明。

  java  动态代理机制依赖于InvocationHandler接口、Proxy类。这是java 实现动态代理必须用到的。

  一、InvocationHandler:该接口中只有一个方法 public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;

             该方法的作用目标对象的方法会转发由InvocationHandle这个接口的invoke方法来调用

 

              

/**
     * invoke 是 InvocationHandler 接口的唯一方法
     * 当我们使用动态代理调用目标对象的方法时,
* 目标对象的方法会转发由InvocationHandle这个接口的invoke方法来调用 * 参数 1、proxy ==> 代理的目标对象 * 2、method ==> 目标对象要调用的方法 * 3、args ==> 目标对象要调用的方法的参数数据 *
*/

 

    以下是源码对invoke方法的解释

/**
     * Processes a method invocation on a proxy instance and returns
     * the result.  This method will be invoked on an invocation handler
     * when a method is invoked on a proxy instance that it is
     * associated with.
*/

 

 

  二、Proxy:Proxy类的作用及时动态创建一个代理对象的类,Proxy提供了许多方式,用了最多的是newProxyInstance

 

/**
     * 
     * @param target
     * @return
     * 
     * Proxy.newProxyInstance(loader, interfaces, h) 说明:
     * Proxy类的作用及时动态创建一个代理对象的类,Proxy提供了许多方式,用了最多的是newProxyInstance
     * 参数  1、loader      ==> 一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
     *     2、interfaces  ==> 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,
     *             如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
     *     3、h           ==> 一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,
     *        会关联到哪一个InvocationHandler对象上
     * 
     * 
     */

 

           以下是源码的解释

 

 

 /**
     * Returns an instance of a proxy class for the specified interfaces
     * that dispatches method invocations to the specified invocation
     * handler.
*/

 

  

  三、动态代理的实现

  1、创建布标对象的接口Hello.java

/**
 * java proxy InvocationHandler 动态代理公共接口
 * 
 * @author dyf
 *
 */
public interface Hello 
    void sayHello();
    void run(String name,int count);

 

  2、创建代理类DynaProxy.java

package cn.dyf.proxy;

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

/**
 * java proxy InvocationHandler 实现公共接口代理对象
 * 动待代理对象需实现InvocationHandler接口,重新invoke方法
 * @author dyf
 *
 */
public class DynaProxy implements InvocationHandler
    
    private Object target;
    
    /**
     * 
     * @param target
     * @return
     * 
     * Proxy.newProxyInstance(loader, interfaces, h) 说明:
     * Proxy类的作用及时动态创建一个代理对象的类,Proxy提供了许多方式,用了最多的是newProxyInstance
     * 参数  1、loader      ==> 一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
     *     2、interfaces  ==> 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,
     *             如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
     *     3、h           ==> 一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,
     *        会关联到哪一个InvocationHandler对象上
     * 
     * 
     */
    public Object bind(Object target) 
        this.target = target;
        return Proxy.newProxyInstance(this.target.getClass().getClassLoader(), 
                this.target.getClass().getInterfaces(), this);
        
    
    
    
    /**
     * invoke 是 InvocationHandler 接口的唯一方法
     * 当我们使用动态代理调用目标对象的方法时,目标对象的方法会转发由InvocationHandle这个接口的invoke方法来调用
     * 参数  1、proxy   ==> 代理的目标对象
     *     2、method  ==> 目标对象要调用的方法
     *     3、args    ==> 目标对象要调用的方法的参数数据
     * 
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
        Object result = null;
        result = method.invoke(this.target, args);
        return result;
    

 

  3、创建App测试类

package cn.dyf.proxy;

public class ProxyApp 
    public static void main(String[] args) 
//        new StaticProxy(new SjHello()).sayHello();
        Hello bind = (Hello)new DynaProxy().bind(new SjHello());
        bind.sayHello();
        bind.run("小明", 100);
        
    

 

以上是关于java Proxy InvocationHandler 动态代理实现详解的主要内容,如果未能解决你的问题,请参考以下文章

Java 动态代理 Proxy

java.lang.NoSuchMethodException: com.sun.proxy.$Proxy

java深入分析Java反射-动态代理 proxy

java.lang.ClassCastException: com.sun.proxy.$Proxy2 cannot be cast to...异常

Appium - 在 PageFactory 获取 java.lang.RuntimeException: java.lang.NoSuchMethodException: jdk.proxy2.$P

java proxy 转包