反射与代理设计模式

如果要想动态的创建代理对象,那么就需要使用一个java.lang.reflect.Proxy程序类,在这个类中提供有一个动态实例化新的代理对象的操作方法:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

在本方法之中参数的作用如下:

· ClassLoader loader:类加载器,确定代理对象的产生使用的类加载器是什么;

· Class<?>[] interfaces:要代理类所实现的接口;

· InvocationHandler h:实现了代理调用的处理;

如果要想实现整个动态代理操作,那么核心的关键除了Proxy类之外,还有一个InvocationHandler接口,那么这个接口定义如下:

public interface InvocationHandler{
    /*
     * 动态代理设计模式之中的代理处理方法
     * @param proxy 代理对象
     * @param method 真实主题要调用的方法,结合本类的真实对象可以反射调用方法(真实主题)
     * @param args 表示执行方法时所需要的参数
     * @return  Method 对象反射调用真实主题方法
     * @throws Throwable
     */
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}

实现动态代理:

 1 package cn.test;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 import java.lang.reflect.Proxy;
 6 
 7 interface ISubject{
 8     public void get();
 9 }
10 class RealISubject implements ISubject{
11     public void get(){
12         System.out.println("吃饭");
13     }
14 }
15 
16 class ProxyImpl implements InvocationHandler{
17     private Object real;
18     /**
19      * 如果要想通过动态代理实现类操作invoke()方法,那么必须创建动态对象,同时要保存被代理对象
20      * 如果要想动态创建代理对象,那么必须首先要知道真实对象
21      * @param obj 要代理的真实对象
22      * @return proxy 动态创建的代理对象
23      *
24      */
25     public Object bin(Object obj){
26         this.real = obj;//保存真实对象
27         return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
28     }
29     public void prepare(){
30         System.out.println("餐厅人员准备食物");
31     }
32     public void after(){
33         System.out.println("餐厅人员清理餐桌");
34     }
35     public Object invoke(Object proxy,Method method, Object[] args) throws Throwable{
36         this.prepare();
37         Object ret = method.invoke(this.real, args); //调用真实方法
38         this.after();
39         return ret;
40     }
41 }
42 public class TestLocal{
43     public static void main(String[] args) {
44         ISubject subject = (ISubject) new ProxyImpl().bin(new RealISubject());
45         subject.get();
46     }
47 }

结果:

餐厅人员准备食物
chifan
餐厅人员清理餐桌

总结:此时的Proxy的代理类不会再局限于某一个特定的接口对象操作,而是可以直接进行所有接口子类对象的代理操作,这就是动态代理设计模式的雏形。

posted on 2016-08-30 15:41  麦牧嘉禾  阅读(112)  评论(0编辑  收藏  举报

导航