当前位置:   article > 正文

GOF之动态代理模式

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

收钱

 

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

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/562346
推荐阅读
相关标签
  

闽ICP备14008679号