举个小栗子解释java动态代理

假设老板有个服务:用户说他自己的名字(xxx)。服务要对其说hello xxx.
老板便买了个机器人来执行这个服务。

那么我们先定义一个服务类型接口:

interface HelloService{
    String sayHello(String name);
}

然后我们让机器人实现这个服务类:

class Robot implements HelloService{
    @Override
    public String sayHello(String name) {
        return "hello " + name;
    }
}

然后我们用这个服务类去服务他人:

public class Demo {
    public static void main(String[] args) {
        Robot robot = new Robot();
        System.out.println(robot.sayHello("zhangsan"));     
    }
}

输出:

hello zhangsan

不错,这样写没有问题。但是,新的问题来了。有个用户lisi,老板不喜欢lisi。老板不会修改机器人,又希望当lisi来用这个服务的时候机器人对他说bye。该怎么办?

老板想到用代理来解决这个问题。找个保安代理机器人。当lisi 来的时候,不让机器人说话,自己冒充机器人声音说bye lisi。

逻辑说通了,那么我们现在来实现这个逻辑。

先写这个保安的逻辑:

class ProxyHandler implements InvocationHandler{
    private Object robot;
    //想让保安代理机器人那就要把机器人交给他。这个object将来存机器人
    public ProxyHandler(Object robot) {
        this.robot= robot;  
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
        if("lisi".equals(args[0])){
            //当参数为lisi的时候,老板不喜欢lisi,那就改为对其说bye bye
            String rs = (String) method.invoke(robot, args);
            System.out.println("the robot return value:"+rs);
            return "bye " + args[0];
        }
        //其他时候正常返回机器人说的话
        return method.invoke(robot, args);

    }
}

接下来我们让保安和机器和为一体。

Robot robot = new Robot();
//构造保安的时候将机器人传入
ProxyHandler baoan = new ProxyHandler(robot);
//proxy为保安和机器一体化的对象
HelloService proxy = (HelloService) Proxy.newProxyInstance(
                robot.getClass().getClassLoader(),
                robot.getClass().getInterfaces(), 
                baoan);

接下来我们测试下结果是不是我们预期的。

//输出:hello zhangsan
System.out.println(proxy.sayHello("zhangsan"));
//本来应该输出:hello lisi,但是由于我们的保安改变了返回值。所以实际输出:bye lisi
System.out.println(proxy.sayHello("lisi"));

完整代码:

public class Demo {
    public static void main(String[] args) {

//      Robot robot = new Robot();
//      System.out.println(robot.sayHello("xxx"));

        Robot robot = new Robot();
        ProxyHandler baoan = new ProxyHandler(robot);
        HelloService proxy = (HelloService) Proxy.newProxyInstance(
                robot.getClass().getClassLoader(),
                robot.getClass().getInterfaces(), 
                baoan);
        //输出:hello zhangsan
        System.out.println(proxy.sayHello("zhangsan"));
        //本来应该输出:hello lisi,但是由于我们的保安改变了返回值。所以实际输出:bye lisi
        System.out.println(proxy.sayHello("lisi"));

    }
}
interface HelloService{
    String sayHello(String name);
}
class Robot implements HelloService{
    @Override
    public String sayHello(String name) {
        return "hello " + name;
    }
}
class ProxyHandler implements InvocationHandler{
    private Object robot;
    public ProxyHandler(Object target) {
        this.robot = target;    
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
        if("lisi".equals(args[0])){
            String rs = (String) method.invoke(robot, args);
            System.out.println("the robot return value:"+rs);
            return "bye " + args[0];
        }
        return method.invoke(robot, args);

    }
}

希望读者看完后可以理解为什么使用代理和如何使用代理。
2016年12月28日22:21:50

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值