002--AOP(JDK动态代理)

来源:互联网 发布:做淘宝的分销要交钱么 编辑:程序博客网 时间:2024/06/03 15:29

AOP

 


 

1 概述

在对静态代理的讨论中,可以发现,如果方法比较多的情况下,为每种方法做代理,是一件重复和繁琐的工作。需要有一种机制能够截获方法调用,从而集中处理。这就是将探讨的动态代理。

在Java中,动态代理是指代理类的生成发生在程序运行时期,根据被代理类动态生成代理类的字节码文件(class文件),并且装载到运行环境中,像其他的类一样使用,该字节码文件的生存期随着运行环境的关闭而消失。

JDK1.3以及之上的版本提供了动态代理的机制,它和反射机制结合在一起。下面将以一个例子说明JDK的动态代理。

 

2 JDK动态代理

2.1 JDK提供的接口和类

  • InvocationHandler接口

该接口的定义如下:

它定义了唯一的方法invoke,该方法的参数为代理对象proxy,截获的方法对象method,和方法调用的参数,返回方法执行的结果。

开发者需要实现该接口,在invoke方法中添加对截获的方法的代理操作,并调用被代理对象的方法。

  • Proxy类

该类是生成代理类的帮助类,它的几个主要方法如下:

public Static Class getProxyClass (ClassLoader loader, Class[] interfaces):根据指定的类加载器和接口获得一个代理类,其中,loader是类加载器,interfaces是被代理类所拥有的接口。 
public Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):根据指定的类加载器、接口以及截获器,返回代理类的一个实例对象。

2.2 Comand接口和ConnectCommand类

我们仍然以静态代理一文中的场景中的Command接口和ConnectCommand类为例说明。Command接口如下:


 

 

 

ConnectCommand类如下,仅作为演示使用。

 

 

2.3基于JDK的动态代理的实现

 截获器InvocationHandler的实现如下:


 

 

ConnectCommandHandler在被代理对象original的方法执行前后,可以做一些代理的操作,这里仅仅输出信息作为演示。

创建代理的类JDKProxyCreator的实现如下:


 

 

测试类如下:

 

 

测试结果如下:

Without proxying:

Excuting command...


With interface proxying(jdk-dynamic):

Before excuting command...

Excuting command...

After excuting command...

 

3 分析总结

分析JDK提供的帮助类Proxy,可以发现,它只支持实现接口方式的代理,不支持继承超类方式的代理,这就意味着,被代理的类必须要有接口,并且需要拦截的方法必须都在接口中进行声明。在本例中,通过截获帮助类Proxy生成的代理类的字节码文件,反编译之后,发现,其类的声明如下:

public final class proxy0 extends Proxy implements Command

其中,proxy0就是动态生成的代理类的名字,在该类的方法中,都会将调用委托到拦截器的invoker方法。

因为JDK提供的动态代理仅支持接口方式的代理,那么如果被代理的类没有实现任何接口,如何处理呢?后续将探讨基于CGLib的动态代理,它同时也支持继承超类的方式的代理。

 

 

 

 

 

 

 

原创粉丝点击