您的位置:首页 > 编程语言 > Java开发

Java 代理之动态代理 (续前)

2016-06-15 17:02 411 查看
...续前一篇

二、动态代理

   动态代理与静态代理相相比,最大的好处就是接口中声明的所有方法都被转移到一个集中的方法中进行处理(即 invoke 方法)。这样做的好处是,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样,在每一个方法里都进行中转。

但是,动态代理类只能代理接口,代理类都需要实现 InvocationHandler 类,并覆写其 invoke() 方法。该invoke() 方法就是所有方法被代理后需要调用的方法,该 invoke() 方法返回的值是被代理接口的一个实现类。

还是以前面的服务生例子为例,创建以下动态代理类:

/**

 * 服务员动态代理类

 *

 * @author ZHULX

 *

 */

public
class
DynamicProxyWaiter implements InvocationHandler {

 

       // 持有被代理的接口对象

       private Object
waiter;

 

       /**

        * 绑定被代理的对象,也就是关联到哪个接口(与具体的实现类绑定)的哪些方法被调用时,执行 invoke
方法。

        *

        * @param waiter

        *           被代理的实现类对象

        * @return返回代理后的对象

        */

       public ObjectbindRelation(Object
waiter) {

<
d113
p>              this.waiter =
waiter;
              ObjectproxyWaiter = Proxy.newProxyInstance(waiter.getClass().getClassLoader(),waiter.getClass().getInterfaces(),this);

              return
proxyWaiter;

       }

 

       /**

        * 所有方法的代理方法

        *

        * @param proxy

        *           代理后的对象

        * @param method

        *           被代理对象即将被调用的方法

        * @param args

        *           即将被调用方法的参数

        * @return返回执行后的代理对象

        */

       @Override

       public Object invoke(Object
proxy, Method method, Object[]
args) throws Throwable {

              Objectresult =
waiter;

              if (method.getName().endsWith("Welcome")) {

                     System.out.println("******
向顾客行90°度鞠躬礼 ******");

                     result =
method.invoke(waiter,
args);

              }else
if
(method.getName().endsWith("Goodbye")) {

                     System.out.println("******
向顾客行45°度鞠躬礼 ******");

                     result =
method.invoke(waiter,
args);

              }

              return
result;

       }

 

}

最后,我再重新创建一个测试类:

/**

 * 测试类

 *

 * @author ZHULX

 *

 */

public
class
Test {

 

       public
static void
main(String[]
args) {

              // 被代理的对象

              IWaiterwaiter = new WaiterImpl();

 

              System.out.println("未代理前的执行结果:");

              waiter.sayWelcome();

              waiter.sayGoodbye();

 

              // 代理对象

              DynamicProxyWaiterhandler =
new
DynamicProxyWaiter();

              IWaiterproxyWaiter = (IWaiter)
handler.bindRelation(waiter);

 

              // 执行代理对象的方法

              System.out.println("\n代理后的执行结果:");

              proxyWaiter.sayWelcome();

              proxyWaiter.sayGoodbye();

       }

 

}

如果一切正常,输出应该如下所示:

未代理前的执行结果:

****** 您好,欢迎光临! ******

****** 您慢走,欢迎再次光临! ******

 

代理后的执行结果:

****** 向顾客行90°度鞠躬礼 ******

****** 您好,欢迎光临! ******

****** 向顾客行45°度鞠躬礼 ******

****** 您慢走,欢迎再次光临! ******

    因此,不难发现,我们可以灵活地在委托类执行某方法前后加入任意的程序逻辑。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: