动态代理

动态代理:(转)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;
    }

 


 


 

posted @ 2019-04-11 17:04  萌胖胖  阅读(227)  评论(0编辑  收藏  举报