• 动态代理


    动态代理:(转)java动态代理实现与原理详细分析

      特点: 字节码随用随创建, 随用随修改

      作用: 不修改源码的基础上对方法增强

      分类: 

        基于接口的动态代理

        基于子类的动态代理

    基于接口的动态代理: 

        涉及的类:Proxy

        提供者:JDK官方

      如何创建代理对象:

        使用Proxy类的newProxyInstance方法

      创建代理对象的要求:  

        被代理类最少实现一个接口, 如果没有则不能使用

      newProxyInstance方法的参数:(查看源码)

      /**  @param   loader the class loader to define the proxy class
         * @param   interfaces the list of interfaces for the proxy class
         *          to implement
         * @param   h the invocation handler to dispatch method 
         * invocations to
         * @return  a proxy instance with the specified invocation handler 
         * of a
         *          proxy class that is defined by the specified class loader
         *          and that implements the specified interfaces
         */
     public static Object newProxyInstance(ClassLoader loader,
                                              Class<?>[] interfaces,
                                              InvocationHandler h)
            throws IllegalArgumentException
        {
            Objects.requireNonNull(h);
    
            final Class<?>[] intfs = interfaces.clone();
            final SecurityManager sm = System.getSecurityManager();
            if (sm != null) {
                checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
            }

        ClassLoader :用于定义代理类的类加载器

        深入理解ClassLoader工作机制(jdk1.8)

          是用于加载代理对象字节码的, 和被代理对象使用相同的类加载器。

        Class[] : 代理类的接口列表   字节码数组

          它是用于让代理对象和被代理对象有相同方法

        InvocationHandler : 用于提供增强的代码

          它是让我们写如何代理, 写一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的

          此接口的实现类都是谁用谁写

    使用匿名内部类实现InvocationHandler接口
    1 IProducer iProducer=(IProducer)Proxy.newProxyInstance (producer.getClass ().getClassLoader (), producer.getClass ().getInterfaces (), new InvocationHandler () {
    2             public Object invoke (Object proxy, Method method, Object[] args) throws Throwable {
    3                 return null;
    4             }
    5         });

       

    不使用匿名内部类实现InvocationHandler接口
    public class MyInvocationHandler<T> implements InvocationHandler {
        private  Object target=null;
        public MyInvocationHandler (Object target) {
            this.target= target;
        }
        public Object invoke (Object proxy, Method method, Object[] args) throws Throwable {
            proxy=this.target;
            //提供增强的代码
            /*
            */
            //获取方法执行的参数-----args[0]
        Object returnValue  = method.invoke(proxy,args);
        return returnValue;
        } 
    }    
    InvocationHandler producerInvocationHandler= new MyInvocationHandler<IProducer> (producer);
    IProducer producerProxy = (IProducer) Proxy.newProxyInstance(producer.getClass().getClassLoader(),
                                           producer.getClass().getInterfaces(),producerInvocationHandler);
    producerProxy.saleProduct(10000f);
    InvocationHandler中的invoke方法:
         * @param   proxy the proxy instance that the method was invoked on  代理调用该方法的代理实例
         *
         * @param   method the {@code Method} instance corresponding to
         * the interface method invoked on the proxy instance.  The declaring
         * class of the {@code Method} object will be the interface that
         * the method was declared in, which may be a superinterface of the
         * proxy interface that the proxy class inherits the method through.
         *
         * @param   args an array of objects containing the values of the
         * arguments passed in the method invocation on the proxy instance,
         * or {@code null} if interface method takes no arguments.
         * Arguments of primitive types are wrapped in instances of the
         * appropriate primitive wrapper class, such as
         * {@code java.lang.Integer} or {@code java.lang.Boolean}.
         *
         * @return  the value to return from the method invocation on the
         * proxy instance.  If the declared return type of the interface
         * method is a primitive type, then the value returned by
         * this method must be an instance of the corresponding primitive
         * wrapper class; otherwise, it must be a type assignable to the
         * declared return type.  If the value returned by this method is
         * {@code null} and the interface method's return type is
         * primitive, then a {@code NullPointerException} will be
         * thrown by the method invocation on the proxy instance.  If the
         * value returned by this method is otherwise not compatible with
         * the interface method's declared return type as described above,
         * a {@code ClassCastException} will be thrown by the method
         * invocation on the proxy instance.
         *
    
    
    
    /**
         * 作用:执行被代理对象的任何接口方法都会经过该方法
         * 方法参数的含义
         * @param proxy   代理对象的引用
         * @param method  当前执行的方法
         * @param args    当前执行方法所需的参数
         * @return        和被代理对象方法有相同的返回值
         * @throws Throwable
         */
        public Object invoke (Object proxy, Method method, Object[] args) throws Throwable {
            proxy=this.proxy;
            //提供增强的代码
    
            //获取方法执行的参数-----args[0]
            Object returnValue =method.invoke(proxy, args);
            return returnValue;
        }
    
    
     


  • 相关阅读:
    P站画师 GTZ taejune 精选4k插画壁纸
    点、向量与坐标系
    一些几何
    画直线算法 Line drawing algorithm
    DX11 学习大纲
    插值 Interpolation
    The History of Computer Graphics
    vue中的请求拦截响应
    Event loop
    小程序使用wx.navigateTo()跳转失败
  • 原文地址:https://www.cnblogs.com/mkl7/p/10690891.html
Copyright © 2020-2023  润新知