Java动态代理

原创 2016年08月31日 15:53:04

代理

有时候我们不希望直接访问对象A,而是希望通过访问中介对象B,由B来访问A,这种方式就是我们所说的代理。这里的类A即为委托类(被代理类),B为代理类。那么使用代理的好处是什么呢?

  1. 隐藏委托类的实现
  2. 实现解耦,在不改变委托类的情况下,对代理类进行修改,实现额外的处理。
    代理分为静态代理和动态代理。

静态代理

所谓静态代理就是程序运行之前代码中存在代理类,静态代理中代理类和委托类也常常继承同一父类或实现同一接口。

public interface Behaviour {
    void method();
}
//委托类
public class Principal implements Behaviour{
    public void method() {
        System.out.println("principle.method");
    }
}
//代理类
public class Agent implements Behaviour {
    private Principal principal;
    public Agent(Principal principal){
       this.principal = principal;
    }
    public void method() {
        principal.method();
    }
}

代理类持有委托类对象的引用,通过调用委托类对象的方法实现代理。使使用者和委托类之间解耦,但是缺点是我们要提前写好代理类。

动态代理

程序运行过程中创建代理类,这种方式叫动态代理。代码中不需要专门去写一个代理类。

动态代理的实现方式
  1. 新建行为接口和委托类
  2. 新建一个类实现InvocationHandler接口,这是负责连接代理类和委托类的中间类必须实现的接口
  3. 通过Proxy类产生代理类对象。
    先来新建行为接口和委托类
public interface Behaviour {
    void method();
}
//委托类
public class Principal implements Behaviour{
    public void method() {
        System.out.println("principle.method");
    }
}

再来写一个类实现InvocationHandler接口,

public class MyInvocation implements InvocationHandler {
    private Object principal;

    public MyInvocation(Object principal) {
        this.principal = principal;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(principal,args);
        return result;
    }
}

这里解释一下InvocationHandler接口里的public Object invoke(Object proxy, Method method, Object[] args) throws Throwable方法各个参数代表的意思,proxy是后面要生成的代理类对象,method表示代理对象被调用的函数。args表示代理对象被调用的函数的参数。
从上面代码我们看到,中介类持有委托类对象引用,在invoke方法中调用了委托类对象的相应方法。实际上,中介类与委托类构成了静态代理关系,在这个关系中,中介类是代理类,委托类就是委托类;代理类与中介类也构成一个静态代理关系,在这个关系中,中介类是委托类,代理类是代理类。也就是说,动态代理关系由两组静态代理关系组成,这就是动态代理的原理。

通过Proxy类产生代理类对象
public class Example {
    public static void main(String args[]) {
        Principal principal = new Principal();//构造一个委托类对象
        MyInvocation myInvocation = new MyInvocation(principal);//构造中介类,并把委托类对象传入
        Behaviour behaviour = (Behaviour) Proxy.newProxyInstance(Behaviour.class.getClassLoader(),
                new Class[]{Behaviour.class},myInvocation);//动态生成代理类对象
        behaviour.method();
    }

}

这里通过Proxy.newProxyInstance(Behaviour.class.getClassLoader(),
new Class[]{Behaviour.class},myInvocation);//动态生成代理类对象
,这个方法的三个参数,第一个参数是定义代理类的Classloader,第二个参数是委托类实现的接口列表,第三个参数是我们实现的invocaition接口实例。
当我们调用代理类的方法时,behaviour.method();,实际会调用MyInvocation里的public Object invoke(Object proxy, Method method, Object[] args)方法,而这个方法里又会调用委托类的相应方法,所以额外的处理逻辑一般都在这个方法里实现。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Java动态代理(JDK和cglib)

  • 2017年07月04日 21:10
  • 246KB
  • 下载

JAVA反射机制和动态代理PDF

  • 2012年12月13日 14:55
  • 263KB
  • 下载

java动态代理(类加载、asm、cglib、javassist)

class文件简介及加载Java编译器编译好Java文件之后,产生.class 文件在磁盘中。这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码。JVM虚拟机读取字节码文件,取出二...

java动态代理

  • 2012年04月30日 21:04
  • 2KB
  • 下载

java 动态代理 简单实例

  • 2011年12月24日 13:52
  • 6KB
  • 下载

Java的CGLib动态代理

CGLib采用非常底层的字节码技术,可以为一个类创建

java动态代理

  • 2012年10月06日 10:37
  • 2KB
  • 下载

java 动态代理实现AOP

  • 2012年05月17日 14:30
  • 139KB
  • 下载

java动态代理中的invoke方法是如何被自动调用的

Java中动态代理的实现,关键就是这两个东西:Proxy、InvocationHandler,下面从InvocationHandler接口中的invoke方法入手,简单说明一下Java如何实现动态代理...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java动态代理
举报原因:
原因补充:

(最多只允许输入30个字)