Java Web之动态代理

作者: YungFan | 来源:发表于2017-01-05 14:14 被阅读622次

动态代理通俗解释:

A接口有c方法,类B实现A接口,原本应该是执行B类中的c方法,可现在不这样做,可以先声明产生B类的代理类B',由它来冒充B类的“兄弟”并“实现”A接口, 对外界来说B'应该也有c方法,可当真正调用它的时候, 它会去执行与它关联InvocationHandler的invoke()方法, 在这个方法里面你可以做很多事情。

Java怎样实现动态代理呢

第一步,我们要有一个接口,还要有一个接口的实现类,而这个实现类就是我们要代理的类。

public interface Subject
{
    public void request();
}

public class RealSubject implements Subject
{
    public void request()
    {
        System.out.println("From real subject!");
    }

}

第二步,我们要自己写一个代理类,它的特点是实现了InvocationHandler接口, 因为代理类的实例在调用实现类的方法的时候,不是去调用真正的实现类的这个方法, 而是调用代理类的invoke()方法,在这个方法中才调用真正的实现类的方法。

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

/**
 * 该代理类的内部属性是Object类型,实际使用的时候通过该类的构造方法传递进来一个对象
 * 此外,该类还实现了invoke方法,该方法中的method.invoke其实就是调用被代理对象的将要
 * 执行的方法,方法参数是sub,表示该方法从属于sub,通过动态代理类,我们可以在执行真实对象的方法前后
 * 加入自己的一些额外方法,这里在方法调用前后打印一句话。
 *
 */

public class DynamicSubject implements InvocationHandler
{
    private Object sub;
    
    public DynamicSubject(Object obj)
    {
        this.sub = obj;
    }
    
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable
    {
        System.out.println("before calling: " + method);
        
        method.invoke(sub, args);
        
        System.out.println(args == null);
        
        System.out.println("after calling: " + method);
        
        return null;
    }   
    
}

上述方法体中method.invoke(owner, args)的解释:执行该method.invoke方法的参数是执行这个方法的对象owner,参数数组args,可以这么理解:owner对象中带有参数args的method方法。返回值是Object,也就是该方法的返回值。

第三步,客户端要用代理类的实例去调用实现类的方法。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Client
{
    public static void main(String[] args)
    {
        RealSubject realSubject = new RealSubject();

        InvocationHandler handler = new DynamicSubject(realSubject);

        Class<?> classType = handler.getClass();

        // newProxyInstance()动态生成一个类并加载到内存
        // 加载到内存要使用加载器,第一个参数是一个类加载器
        Subject subject = (Subject) Proxy.newProxyInstance(classType
                .getClassLoader(), realSubject.getClass().getInterfaces(),
                handler);

        subject.request();

        System.out.println(subject.getClass());

    }

}

对第三步的解释

主要是以下代码:

Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

该方法主要做了如下工作:

  • 根据参数loader和interfaces调用方法 getProxyClass(loader, interfaces) 创建代理类$Proxy0,该代理类实现了预先定义的接口(如上面的Subject),并继承了Proxy类。
public final class $Proxy0 extends Proxy implements Subject
  • 实例化$Proxy0(创建代理对象)并在构造方法中把 InvocationHandler(这里handler 是它的实例)传过去

  • $Proxy0调用父类Proxy的构造器,为InvocationHandler 赋值:

public $Proxy0(InvocationHandler invocationhandler)
{
  super(invocationhandler);
}
========================================================
class Proxy
{
   protected InvocationHandler h;
   protected Proxy(InvocationHandler h) 
   {
         this.h = h;
   }
}
  • 将这个$Proxy0类强制转型成接口类型,当执行接口中的方法时(如上文强转成Subject后调用request()方法),就调用了$Proxy0类中实现的接口方法,在该方法中会调用父类Proxy中的invoke()方法,即InvocationHandler.invoke(),达到做一些其他工作的效果。
public final void request()
{
  try
  {
      //m是通过反射得到的方法名 Method类型
      super.h.invoke(this, m, null);
      return;
  }
  catch (Error e)
  {

  }
  catch (Throwable throwable)
  {
    throw new UndeclaredThrowableException(throwable);
  }
}

相关文章

  • Java 动态代理

    java的动态代理机制详解 JDK动态代理详解 Java核心技术点之动态代理

  • Java Web之动态代理

    动态代理通俗解释: A接口有c方法,类B实现A接口,原本应该是执行B类中的c方法,可现在不这样做,可以先声明产生B...

  • Java代理模式之JDK动态代理

    了解什么是动态代理模式,可参考Java设计模式之代理模式 简介 JDK动态代理是java.lang.reflect...

  • Spring AOP源码解析

    欲了解AOP,需先了解Java动态代理;欲了解Java动态代理,先熟悉设计模式之代理模式。入门有道,先从简学。 1...

  • JDK动态代理详解

    JDK动态代理详解 java动态代理类 Java动态代理类位于java.lang.reflect包下,一般主要涉及...

  • 公共知识复习

    动态代理 公共技术点之 Java 动态代理 @codeKK 开源站 屏幕适配 android机型适配终极篇 - C...

  • Java动态代理从入门到原理再到实战

    目录 前言 什么是动态代理,和静态代理有什么区别 Java动态代理的简单使用 Java动态代理的原理解读 动态代理...

  • java反射和动态代理

    java动态代理Proxy.newProxyInstance 详解java代理机制(静态代理、动态代理)以及使用场景

  • 保存java 动态代理生成的字节码文件

    保存java 动态代理生成的字节码文件 在Java中,常用的动态代理技术有JDK的动态代理和cglib动态代理,不...

  • 设计模式之代理

    设计模式之代理模式 一、定义 在Java中代理的实现一般分为三种:JDK静态代理、JDK动态代理以及CGLIB动态...

网友评论

    本文标题:Java Web之动态代理

    本文链接:https://www.haomeiwen.com/subject/xykzvttx.html