动态代理模式学习

13年前

   前面初始了静态代理,如果有新的代理,那么就右要写上一个代理类,将真实代理作为代理的属性,考虑到java机制1.3支持 类反射机制,因此聪明的人民,就知道了,可以动态代理  ,下面是代码试验
      1:首先定义公共接口,为什么要定义工作接口呢,这个问题,后面再说
**
 *
 * @author sunshine
 *  动态代理机制试验
 */
public interface DyNamicInterFace {
 /**
  *
 * @Function: DyNamicInterFace.java
 * @Description: 动态代理请求
 *
 * @throws Exception
 * @return:返回结果描述
 * @throws:异常描述
 *
 * @version: v1.0.0
 * @author: 浪子
 * @date: 2011-8-25 下午08:29:02
 *
 * Modification History:
 * Date         Author          Version            Description
 *---------------------------------------------------------*
 * 2011-8-25     浪子           v1.0.0               修改原因
  */
 public void dyNamicRequest() throws Exception;
 
    public void dyNamicRequest(String name) throws Exception;
   
    public void dyNamicRequest(String name,int i) throws Exception;
}

 2:java动态代理,要用到java.lang.reflect.Method;java.lang.reflect.Proxy;  类,要实现动态必须实现java.lang.reflect.InvocationHandler(是代理实例的调用处理程序 实现的接口。)的接口 InvocationHandler接口中的invok方法,Proxy会执行这个要看jdk源码 容积Constructor 构造器会构造 InvocationHandler h的实例,这就是为什么要实现InvocationHandler  接口
invok  方法第二个参数Method 是代理实现类的方法对象,第三个Method要调用的方法里面参数的值
实现动态代理,可以实现自己的接口,但是要动态代理必须要实现InvocationHandler    接口
         2:动态代理类 实现   InvocationHandler  接口
**
 * @author sunshine
 * 动态代理的动态实现类
 */
public class DyNamicInterFaceImpl implements DyNamicInterFace,InvocationHandler {
   public void dyNamicRequest(String name, int i) throws Exception {
  // TODO Auto-generated method stub 
 }
 public void dyNamicRequest() throws Exception {
  // TODO Auto-generated method stub
    System.out.println("aaaaa ");
 }
 public void dyNamicRequest(String name) throws Exception {
  // TODO Auto-generated method stub
    System.out.println("bbbb ");
 }
 private Object proxyObject;      //定义一个 Object  ,这样在初始化的时候,或者其他方式,进行向上转型成Object,
   public DyNamicInterFaceImpl()
   {
   
   }
   public DyNamicInterFaceImpl(Object proxyObject)
   {
    this.proxyObject=proxyObject;
   }
 public Object invoke(Object proxy, Method method, Object[] aobj)
   throws Throwable {
 
  System.out.println("开始调用 ");
 
  System.out.println("调用的MethodName="+method.getName());
 // System.out.println("调用的对象ObjectAobj="+aobj.length);
  int i=0;
  while(aobj!=null&&aobj.length>0&&aobj.length>i)
  {
  
   System.out.println("调用的对象ObjectAobj参数="+aobj[i]);
   i++;
  }
  Object o=method.invoke(proxyObject, aobj);
 
  System.out.println("invokeObject="+o);
  return o;
 }
 
 
 //客户端测试
 public static void main(String []args) throws Exception
 {
 
 
  BusinessObject realObject=new BusinessObject();  //需要代理的业务对象
  DyNamicInterFaceImpl  dyNamic=new DyNamicInterFaceImpl(realObject); //动态代理对象
     从上面两行代码,可以看出是动态代理dyNamic ,代理 realObject真实对象
  Class  c=Class.forName("test.pro.Pen");
  Object o=c.newInstance();
  System.out.println("ssssss="+o);
 
      //      System.out.println("aaa="+c.getName());
           
    // Proxy.newProxyInstance(c.getClassLoader(), new Class[]{c}, dyNamic);
//DyNamicInterFace
为什么要转型为 DyNamicInterFace   接口呢,这样就要求 业务对象要implements 公共接口,因为在newProxyInstance中 第1个参数(类加载classLoader),第2个参数(代理类要实现的接口类),第三个参数,调用处理器,
  DyNamicInterFace dyNamicObjec=(DyNamicInterFace)Proxy.newProxyInstance(DyNamicInterFace.class.getClassLoader(),new Class[]{DyNamicInterFace.class}, dyNamic);    
  //DyNamicInterFace dyNamicObjec=(DyNamicInterFace)Proxy.newProxyInstance(realObject.getClass().getClassLoader(), realObject.getClass().getInterfaces(), dyNamic);   
  dyNamicObjec.dyNamicRequest();
     // o.dyNamicRequest();
  dyNamicObjec.dyNamicRequest("123");
   //  System.out.println("object="+o.getClass().getName());
  dyNamicObjec.dyNamicRequest("1234", 1);
 }
 测试结果:
testPen
ssssss=test.pro.Pen@affc70
开始调用
调用的MethodName=dyNamicRequest
BusinessObject
invokeObject=null
开始调用
调用的MethodName=dyNamicRequest
调用的对象ObjectAobj参数=123
BusinessObject===123
invokeObject=null
开始调用
调用的MethodName=dyNamicRequest
调用的对象ObjectAobj参数=1234
调用的对象ObjectAobj参数=1
BusinessObject==1234
BusinessObjectI==1
invokeObject=null