zoukankan      html  css  js  c++  java
  • 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);
            
        }
    }
  • 相关阅读:
    Extjs Google的Suggest的自动提示 从后台取数据
    vue 使用gojs绘制简单的流程图
    网络流24题の详解
    Codeforces Round #587 (Div. 3) F. WiFi(dp+线段树)
    Codeforces Round #588 (Div. 2) E. Kamil and Making a Stream(dfs)
    Spring使用经验之StandardServletMultipartResolver实现文件上传的基本配置
    MySQL + Amoeba 负载均衡、主从备份方案
    SubVersion(SVN)的安装配置使用
    Tomcat Https配置
    Eclipse 常用快捷键清单
  • 原文地址:https://www.cnblogs.com/dyfbk/p/11121135.html
Copyright © 2011-2022 走看看