欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java静态代理和动态代理

程序员文章站 2022-06-17 19:53:42
...

 接口

interface ProxyInterface{
    void say(String st);
}

被代理类

class ByAgency implements ProxyInterface{
  public void say(String str){
      System.out.println(str);
  }
}

静态代理的代理类

/*静态代理的代理类*/
class Agencys implements ProxyInterface{
  private ProxyInterface pif;

  public Agencys(ProxyInterface pif){
      this.pif = pif;
  }

  public void say(String str){
      System.out.println("正在代理");
      pif.say(str);
      System.out.println("代理完成");
  }
}

静态代理调用方法

public static void testAgency(ProxyInterface pi){
    pi.say("测试");
}
public static void main(String[] args){
    Agencys ag = new Agencys(new ByAgency());
    ag.testAgency(ag);
}

动态代理的代理类

class ProxyObject implements InvocationHandler{
    private Object proxied = null;
    public ProxyObject(){}
    public ProxyObject(Object proxied){
        this.proxied  = proxied;
    }
    public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
        System.out.println("正在代理");
        Object obj = arg1.invoke(proxied, arg2);
        System.out.println("代理完成");
        return obj;
    };
}

动态代理调用方法

public static void testAgency(ProxyInterface pi){
    pi.say("测试");
}
public static void main(String[] args){
    ProxyInterface proxy = (ProxyInterface)Proxy.newProxyInstance(ProxyInterface.class.getClassLoader(),new Class[]{ProxyInterface.class}, (InvocationHandler) new ProxyObject(new ByAgency()));
    /*
        newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)各参数说明
        loader:类装载器,获取方式*.class.getClassLoader()
        interfaces:代理接口
        h:调用ProxyObject构造器新建对象
     */
    testAgency(proxy);
}

代理模式的共同优点:可以在原代码的基础上添加额外的功能,同时不会接触到原码。
静态代理:当需求要代理多个不同的接口类时,代码量会非常大,且代码都是很相似的,复用性差
动态代理:通过实现InvocationHandler类,调用Proxy.newProxyInstance静态方法,会根据传入的参数自动创建代理类。
                  并返回实例对象

下面分析动态代理时自动创建代理类过程:

/*调用自动创建代理类方法*/
ProxyInterface proxy = (ProxyInterface)Proxy.newProxyInstance(ProxyInterface.class.getClassLoader(),new Class[]{ProxyInterface.class}, (InvocationHandler) new ProxyObject(new ByAgency()));
testAgency(proxy);

原码解析:

java静态代理和动态代理

由源码很容易就能看出来,该方法首先使用getProxyClass0方法传参类装载器和代理类接口来新建并获取一个代理类的Class,然后通过反射机制来返回该代理类的实例对象