结构模式---动态代理

动态代理

动态代理是相对静态代理(https://blog.csdn.net/weixin_43060721/article/details/82313877)而言,java动态代理是基于自动生成class文件字节码,然后将字节码动态(运行期而非编译器)加载到classloader,然后调用接口其实是调用字节码的代理类的对象的方法;相比于静态代理而言,不需要提前将类进行配置好,并且可以服务多个接口,比如写一个代理类,既可以代理A接口(让字节码类实现A接口的所有方法)也可以代理B接口((让字节码类实现B接口的所有方法),那就可以面向接口编程(AOP),而静态代理做不到这一点,java中使用动态代理如下:
接口和实际类:

public interface Subject {
    public void print();
}
public class RealSubject implements Subject {
    @Override
    public void print() {
        System.out.println("realSubject method!");
    }
}

动态代理调用接口:

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

public class SubjectInvocationHandler implements InvocationHandler {
    private Subject subject;

    public SubjectInvocationHandler(Subject subject) {
        super();
        this.subject = subject;
    }

    /**
     * proxy:代表java自动生成$Proxy0.class的实例
     * method:接口定义的方法
     * args:方法的入参,可以为null
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before");
        System.out.println("method invoke()");
        Object result = method.invoke(subject, args);
        System.out.println("after");
        return result;
    }
}

客户端:

import java.lang.reflect.Proxy;

public class Client {
    public static void main(String[] args) {
        //打开java生成代理类的开关
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
        RealSubject realSubject = new RealSubject();
        Subject subject = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(),
                new Class[] { Subject.class }, new SubjectInvocationHandler(realSubject));
        subject.print();
    }
}

结果:

before
method invoke()
realSubject methodafter

java自动生成类的位置:
这里写图片描述
自动生成类的字节码:

/*** Eclipse Class Decompiler plugin, copyright (c) 2016 Chen Chao (cnfree2000@hotmail.com) ***/
package com.sun.proxy;

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

public final class $Proxy0 extends Proxy implements Subject {
    private static Method m1;
    private static Method m3;
    private static Method m2;
    private static Method m0;

    public $Proxy0(InvocationHandler paramInvocationHandler)
    throws 
  {
    super(paramInvocationHandler);
  }

    public final boolean equals(Object paramObject)
    throws 
  {
    try
    {
      return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

    public final void print()
    throws 
  {//此处调用print()方法
    try
    {
      this.h.invoke(this, m3, null);//这里会将自己传给invokeHandler
      return;
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

    public final String toString()
    throws 
  {
    try
    {
      return ((String)this.h.invoke(this, m2, null));
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

    public final int hashCode()
    throws 
  {
    try
    {
      return ((Integer)this.h.invoke(this, m0, null)).intValue();
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals",
                    new Class[] { Class.forName("java.lang.Object") });
            m3 = Class.forName("Subject").getMethod("print", new Class[0]);
            m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
            m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
            return;
        } catch (NoSuchMethodException localNoSuchMethodException) {
            throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
        } catch (ClassNotFoundException localClassNotFoundException) {
            throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值