【note】 代理模式


代理模式是常用设计模式之一,当一个对象不适合或者不能直接引用另一个对象时,使用代理对象做中介,通过代理对象访问目标对象。 并且可在代理对象中扩展目标对象的功能

如同经纪人代办事情一样,客户通过代理对象访问目标对象,可以实现权限的控制。同时代理对象可以代处理一些复杂的事务,减轻目标对象的负担。


java中代理模式有三种实现:

静态代理

  • 假设我们有一个client对象需要访问target目标对象请求一些事务处理,client无法直接访问target,只能通过我们提供的Myproxy代理对象:
  1. 创建目标类的接口 ITarget.java

– 提供一个hadleThings 事件处理方法

  1. 创建目标类 Target.java

– 目标类实现ITarget接口 实现其中的处理方法.

  1. 创建代理类MyProxy.java

– 代理类需要与目标类实现相同的接口,重写方法,可在此处扩展目标对象的功能。
– 在类中维护一个目标类对象的引用,通过这个引用来访问目标对象的方法。

  1. 创建客户类使用代理对象实现需要的操作:

运行结果:

代理对象预处理…
目标对象处理…
代理对象处理结束…

可见客户通过代理对象实现了目标对象的功能,并且在代理对象中扩展了功能。实现预处理和善后。

  • 缺点:如果接口和需要代理的类增多, 需要为每一个类创建一个代理类。代码量多。 如果目标类扩展方法,代理类需要同时扩展,不易维护。

动态代理

动态代理解决了静态代理不易维护和代理类多的缺点。动态生成代理对象。仅需一个代理工厂类

java中主要有两种动态代理方式:

JDK提供的Proxy类

还是上面的例子,Target类 和 ITarget类保持不变

  • 代理类MyProxy.java修改如下:

  • 然后客户端使用代理方法如下:

  • 运行结果:

    代理开始….
    目标对象处理…
    代理结束….

  • 可以发现动态代理的优点,不用实现与目标类相同的接口,仅需一个代理类,几乎可以代理所有类和方法

  • 这个代理有一个缺陷是要求被代理的类需要是实现了接口的类。如果目标类没有实现任何接口,不能用这种方式代理

Spring核心包中的Cglib代理

Cglib代理不需要目标类实现接口.
Cglib代理封装在了封装在spring核心包spring-core 中.使用需要先导入此包。
Cglib产生的代理对象是目标对象的子类
Calib代理广泛应用于Aop

使用cglib代理MyProxy.java如下:

  • 客户端使用代理对象方法同上一个不变。

  • 运行结果:

    cglib代理开始…
    目标对象处理…
    cglib代理结束…