动态代理的使用方式

一、简介
    首先介绍下什么是代理,所谓代理就是当原有的类的方法不足以满足我们的需求的时候,我们需要额外进行一些其他的操作的时候,为了尽量不改写业务逻辑,我们不直接调用类本身,而是借助另一个包装好了所有需求的方法的类来实现,当然,这个类里也可以调用原有类的方法,如果需要调用原有类的方法的话(大多数情况下)就需要让该类持有原类的一个对象作为他的成员变量,以方便对原有类中方法的调用。那么这个类就可以称之为代理类了,代理的工作流程如下:
    代理本身又分为静态代理和动态代理,这里的静态和动态分别指的是什么呢,我们知道,要让代理类执行原有类里的方法,我们得让代理类持有原有类的对象,这就意味着,如果有多个类需要代理,我们就得写多个代理类,这个是静态代理,如果是动态代理的话,只需要一个代理类就可以搞定,因为动态代理类不需要持有原类的对象,他需要代理类实现InvocationHandler接口,这个接口有一个需要实现的方法:public object invoke(Object proxy, Method method, Object[] args);这个方法里面我们要写的就是动态调用的业务逻辑了,可以调用method.invoke(proxy,args)来调用proxy对象对应的method方法,传入args参数,并返回object返回值,那问题来了,这个invoke函数是谁调用的呢,这个invoke函数其实是由代理对象调用接口里的方法动态调用的,换句话说,代理对象定义为接口类型的,当他调用接口里的方法的时候,并不是调用实现类里的方法,而是转头调用了这个invoke的方法,那问题又来了,如何获取代理对象呢,可以通过Proxy.newProxyInstance方法获取,将其返回类型强转成对应的接口类型,就可以调用接口里的方法了。返回类型不能转成实现类的类型,不然会报错,报一个类转换错误。
 
二、涉及到的类
InvocationHandler    说明:这是一个接口,代理类实现这个接口,然后实现接口中的invoke方法,作为回调使用的方法。
Proxy    说明:用来获得一个代理对象
 
三、设计的结构
从上往下说吧:
  1. 首先所有准备被代理的类要各自有一个接口
  1. 可以有多个准备被代理的类,里面封装好业务逻辑方法
  2. 要有一个实现了InvocationHandler的代理类,如果需要调用原有类的方法,在代理类中可以封装一个Object类型的成员变量,必须要实现好invoke方法,封装好需要代理的逻辑,可以通过调用method.invoke(object,args)的方法调用对应object对象的method方法,并传入args参数,其中object对象就是我们上面说的成员变量。
  3. 通过Proxy.newProxyInstance方法获取一个代理对象,需要传入三个参数:被代理类的类加载器,被代理类的接口列表,代理类对象实例。
  4. 代理对象强转成对应的接口类型,并调用接口里的方法,可以接收返回值。
 
注:代理对象和代理类对象实例不是一个事情哈,代理对象是通过Proxy.newProxyInstance获取到的,可以强转成接口类型的,代理类对象是指我们定义的实现InvocationHandler的类的对象实例。
 
四、调用方式
这里可能有点冗余,这里是从下往上说的:
  1. 通过Proxy.newProxyInstance方法获取一个代理对象,需要传入三个参数:被代理类的类加载器,被代理类的接口列表,代理类对象实例。
  2. 将这个代理对象强转成对应的接口类型,并调用接口里的方法,可以接收返回值。
  3. 上一步操作将会自动跳用代理类里的invoke方法
  4. invoke方法里可以通过执行:method.invoke(object,args)调用object对象的method方法,并传入args参数,可以接收返回值。这个object需要提前写成Object类型的成员变量,在第一步需要代理类对象实例,可以在获取实例的时候就把对应的类(被代理的类)生成的对象传进去。
  5. 上一步中调用method方法会自动调用object对象里的method方法。
  6. object对象对应的类(被代理的类)需要继承接口,因为第一步的时候就要拿到对应被代理类的接口列表。
 
五、范例代码
接口:
1 package goods;
2  
3 public interface Healthy_drink {
4     void sell();
5     int getMoney();
6 }
 
被代理的类:
 1 package goods;
 2  
 3 public class Water implements Healthy_drink{
 4     private int money;
 5  
 6     public Water(){
 7  
 8     }
 9  
10     public Water(int money){
11         this.money = money;
12     }
13  
14     @Override
15     public int getMoney(){
16         return this.money;
17     }
18  
19     @Override
20     public void sell() {
21         System.out.println("water has selled by " + this.money);
22     }
23 }
 
代理类:
 1 package proxy;
 2  
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5  
 6 public class Dynamic_proxy implements InvocationHandler {
 7     private Object object;
 8  
 9     public Dynamic_proxy(){
10  
11     }
12  
13     public Dynamic_proxy(Object object){
14         this.object = object;
15     }
16  
17     @Override
18     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
19         System.out.println("through dynamic proxy");
20         System.out.println(proxy.getClass().getName());
21         Object result = method.invoke(object, args);
22         return result;
23     }
24 }
 
调用:
1 Water water = new Water(10);
2 Dynamic_proxy dynamic_proxy;
3 int money;
4 dynamic_proxy = new Dynamic_proxy(water);
5 Healthy_drink water_proxy = (Healthy_drink) Proxy.newProxyInstance(Water.class.getClassLoader(), Water.class.getInterfaces(), dynamic_proxy);
6 money = water_proxy.getMoney();
7 System.out.println("water value is " + money);
8 water_proxy.sell();
 
posted @ 2018-05-18 12:26  shuxte  阅读(1504)  评论(0编辑  收藏  举报