详细看懂动态代理使用:以胡歌和经纪人的例子

15 篇文章 0 订阅
12 篇文章 0 订阅

动态代理分为两个部分:
1、动态
(1)一个代理对象(比如娱乐圈的经纪人)可以代理多个被代理对象
(2)被代理对象的多个行为可以被代理
2、代理
被代理对象是真实实现功能的人,代理对象只是增强被代理对象的功能。这里的增强是指在被代理对象实现功能的前后,设置一些
其他的行为,比如在胡歌表演(调用被代理对象的行为)前收钱,在胡歌表演后要求追加合同。
第一步:

public interface Ihuge {

    //定义一个接口:被代理人需要被代理的功能

    void sing(int money);
    void dance(int money);
    void act(int money);
}

第二步:

public class Huge implements Ihuge {

    /*定义被代理对象(比如胡歌)的行为:
    1、需要交给代理对象代理的行为:

    sing、dance、act 和对应的接口中的行为一致

    2、不需要交给代理人代理的行为

    自然不用写入接口
     */

    @Override
    public void sing(int money) {
        System.out.println("胡歌演唱仙剑主题曲");
    }

    @Override
    public void dance(int money) {
        System.out.println("胡歌跳钢管舞");
    }

    @Override
    public void act(int money) {
        System.out.println("胡歌拍新戏");
    }
    public void show(){
        System.out.println("胡歌要走秀");
    }

第三步:代理对象必须要实现InvocationHandler(调用处理器)的功能,实现其中的invoke方法

public class Agent implements InvocationHandler {
    private Object obj;//被代理对象的实例

    public Agent() {
    }
    //代理对象的无参构造

    public Agent(Object obj) {
        this.obj = obj;
    }
    //代理对象的有参构造

    @Override
    /*Object proxy 暂时不用管什么意思,不影响使用
        Method method 描述代理对象可以增强哪些功能(比如有的经纪人只代理明星的唱歌业务)
       Object[] args  参数的集合(被代理对象的被代理方法里的参数,如明星唱歌要收费等)
       **/
    public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
        /*在实现invoke(即被代理对象的行为--唱歌、跳舞之前),代理对象需要增强的行为写在前面;
        同理,之后要增强的行为写在invoke行之后
                **/
        /*如果对被代理对象的不同行为有不同的增强,就使用if,获取方法名,然后针对性地操作
        如代理唱歌,抽一成,事后签演唱会合同;
        代理跳舞,抽两成,事后签商演合同;
         */
        Object invoke=null;
        /*定义invoke接受 invoke方法的返回值对象——即调用的具体method的返回值对象,
        如sing的返回值是void,那这里返回值是null.
         */
        if ("sing".equals(method.getName())){
            System.out.println("经纪人抽取了" + ((int)((int)(args[0]) * 0.1)) + "元钱");
            invoke=method.invoke(obj,args);//输入对象实例(测试类中new一个胡歌)和参数,有异常抛出即可
            System.out.println("签订演唱会合同");
            return invoke;
        }
        //除了唱歌以外,代理人的增强方式一样
        System.out.println("经纪人收取代理费10000元,一次性收取到位");
        invoke=method.invoke(obj,args);
        System.out.println("演出后,大家纷纷鼓掌");
        return invoke;
    }
}

第四步:测试类

public class Test {
    public static void main(String[] args) {
        Huge huge = new Huge();//创建被代理对象的实例

        Ihuge ihuge = (Ihuge)Proxy.newProxyInstance(huge.getClass().getClassLoader(),
                huge.getClass().getInterfaces(), new Agent(huge));
        /*Proxy.newProxyInstance
        需要三个参数:类加载器、被代理兑现所实现的所有接口,代理接口
        创建一个代理功能的对象,强转为需要增强的功能的接口Ihuge
         */

        //调用功能即可
        ihuge.sing(10000);
        ihuge.dance(20000);
        ihuge.act(100000);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值