GOF之动态代理模式

                       GOF之动态代理模式

                         动态代理模式


  

我们在先前的学习中,已经学习了如何使用静态代理模式。那么接下来我们要学习的就是动态代理的模式。

 所谓的动态代理模式,也就是我们不需要自己再写一个代理的角色。而通过一些工具的调用或者说是一些API的调用,我们就可以这样生成一个代理的角色。现在我们就来学习一下如何利用Java JDK中的相关的工具来生成代理的角色。

  package com.lg.dynamicProxy;

 

/**

 * Created by 鏉庢灉 on 2016/8/8.

 */

 

 

/*真实角色和代理角色都需要实现的接口*/

public interface Star {

    /*面谈*/

    void confer();

    /*签合同*/

    void signContract();

    /*订机票*/

    void bookTicket();

    /*唱歌*/

    void sing();

    /*收尾款*/

    void collectMoney();

}

 

 

package com.lg.dynamicProxy;

 

/**

 * Created by 鏉庢灉 on 2016/8/8.

 */

/*这是实现了明星接口的真实的角色*/

public class RealStar implements  Star {

    @Override

    public void confer() {

        System.out.println("RealStar Confer");

    }

 

    @Override

    public void signContract() {

        System.out.println("RealStar signContract");

    }

 

    @Override

    public void bookTicket() {

        System.out.println("RealStar bookTicket");

    }

 

    @Override

    public void sing() {

        System.out.println("RealStar(周杰伦 本人) sing");

 

    }

 

    @Override

    public void collectMoney() {

        System.out.println("RealStar collectMoney");

    }

}

 

 

 

package com.lg.dynamicProxy;

 

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

 

/**

 * Created by 李果 on 2016/8/8.

 */

/**

 *

 * @author 李果

 * 这是反射包下的一个核心的接口。

 *

 */

public class StarHandler implements InvocationHandler {

/**

 * 通过组合的方式来调用真实角色的方法。

 */

    private RealStar realStar;

 

    public StarHandler(RealStar realStar) {

        this.realStar = realStar;

    }

    /**

     * 这个是核心的方法

     * 这个方法就要涉及到我们以前说过的反射的知识了

     * method指的就是我们要调用的那个方法

     * args指的就是我们需要传入的给方法的参数

     */

    @Override

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

        method.invoke(realStar, args);

        return null;

    }

}

 

 

 

package com.lg.dynamicProxy;

 

import java.lang.reflect.Proxy;

 

/**

 * Created by 李果 on 2016/8/8.

 */

public class Client {

    public static void main(String[] args) {

        RealStar realStar = new RealStar();

        StarHandler handler = new StarHandler(realStar);

        /**

         * 这是动态生成一个代理的类。这个类需要传入的参数是类加载器,代理角色和真实

         * 角色的公共的接口。

         * 还有一个就是handler类。

         * 这是要注意的。

         */

        Star proxory = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class}, handler);

        /**

         * 在这里实际上调用的都是真实 角色的方法

         */

        proxory.confer();

        proxory.signContract();

        proxory.sing();

        proxory.collectMoney();

 

    }

}

 

 

最后的输出的结果为:

RealStar Confer

RealStar signContract

RealStar(周杰伦 本人) sing

RealStar collectMoney

 

 

从输出的结果我们可以看到:

通过动态生成的代理角色,在调用相关方法的时候,其实调用的都是真实角色的方法。这是要注意的。

  也因为是这样,我们可以通过在public Object invoke(Object proxy, Method method, Object[] args) throws Throwable

这个方法中,做更多的处理。达到我们想要的效果。

比如说,我们可以在这个方法中,在调用sing()方法以前,我们可以处理一些事情。

sing()方法以后,我们也可以处理一些事情。比如说,我们将这个方法的实现改成下面

的内容:

package com.lg.dynamicProxy;

 

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

 

/**

 * Created by 李果 on 2016/8/8.

 */

/**

 *

 * @author 李果

 * 这是反射包下的一个核心的接口。

 *

 */

public class StarHandler implements InvocationHandler {

/**

 * 通过组合的方式来调用真实角色的方法。

 */

    private RealStar realStar;

 

    public StarHandler(RealStar realStar) {

        this.realStar = realStar;

    }

    /**

     * 这个是核心的方法

     * 这个方法就要涉及到我们以前说过的反射的知识了

     * method指的就是我们要调用的那个方法

     * args指的就是我们需要传入的给方法的参数

     * 当然我们如果需要返回参数的话,我们

     * 也可以返回参数

     * 这是要注意的

     */

    @Override

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

     Object obj=null;

/*真正sing()之前需要处理的内容*/

     System.out.println("面谈");

     System.out.println("签合同");

     System.out.println("订机票");

     if(method.getName().equals("sing")){

         obj= method.invoke(realStar, args);

     }

/*唱歌以后需要处理的事情*/

     System.out.println("收钱");

    

        return obj;

    }

}

 

我们在Client中调用的方法如下:

package com.lg.dynamicProxy;

 

import java.lang.reflect.Proxy;

 

/**

 * Created by 李果 on 2016/8/8.

 */

public class Client {

    public static void main(String[] args) {

        RealStar realStar = new RealStar();

        StarHandler handler = new StarHandler(realStar);

        /**

         * 这是动态生成一个代理的类。这个类需要传入的参数是类加载器,代理角色和真实

         * 角色的公共的接口。

         * 还有一个就是handler类。

         * 这是要注意的。

         */

        Star proxory = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class}, handler);

       

        proxory.collectMoney();

 

    }

}

 

这时候输出的结果为:

面谈

签合同

订机票

收钱

 

 

如果我们在Client中调用的方法如下:

那么输出的结果为:

面谈

签合同

订机票

RealStar(周杰伦 本人) sing

收钱

 

以上就是关于动态代理模式的全部的内容。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱coding的同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值