首页 > 代码库 > 详解java动态代理

详解java动态代理

生活中的代理:

比如一个明星成名了以后,是需要有一个代理的,因为太多人想找他签名,应付不来,那么这个时候代理的作用是拦截你对真正明星的访问,他可以拦截下来收点费用,再叫真正的明星过来为你签名。

程序中的代理:

1,要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理、日志、计算方法的运行时间、事务管理、等等,你准备如何做?

2,编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码

下图显示了在程序中代理的调用原理(代理对象的存在就是为了拦截对真实对象的访问):


说完了代理的概念和原理,下面我们进入java的代理机制。在java中,一个类如果想产生代理类,那么这个类必须实现特定的接口,代理类与被代理类实现相同的接口。在java中,代理又分为静态代理和动态代理,下面我们介绍静态代理,请看以下代码:

<script src="https://code.csdn.net/snippets/333863.js" type="text/javascript"></script>
被代理类Dog和代理类Proxy都实现了Animal接口,在Proxy类中定义一个变量记住真正要代理的类,并由构造方法传参。当调用代理类的方法时,那么就调用被代理类Dog的相应方法,并且在调用目标方法前后做了一些工作。

通过静态代理,我们发现了它存在以下的不足:

1,如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。 

2,代理与真实角色一一对应的,这样对每一个类,都要有一个代理类与之对应,这样代码的复用率就下降

为了解决以上的问题,java为我们引入了动态代理,jdk动态代理就是JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。请看以下代码

<script src="https://code.csdn.net/snippets/333967.js" type="text/javascript"></script>
这里的代理类是在程序运行的时候动态产生的,很多人搞不懂动态生成的类内部结构是如何的,请看如下代码:
<script src="https://code.csdn.net/snippets/333995.js" type="text/javascript"></script>
其实动态代理生成的类和上面的代码很像,不信你们仔细想想。
通过上面的程序可以看出,动态代理最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样在每一个方法进行中转。