Java动态代理过程分析


1   什么是代理模式?

   为其他对象提供一种代理以控制对这个对象的访问。

2   代理模式有什么好处?

 在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。主要用来做方法的增强,让你可以在不修改源码的情况下,增强一些方法,在方法执行前后做任何你想做的事情(甚至根本不去执行这个方法)


动态代理的流程图:

      



代码:

  定义接口:


  public interface people {

     public List eat();

    public void sport();

    }

 

 

接口的实现类:

  

    public class zhangsanimplements people {


        public List eat() {

          System.out.println("张三吃饭!");

           List list=new ArrayList();

        list.add("haha");

     return list;     

}

 


    public void sport() {

        }

}

 

 

   现在我想对这个类的eat()方法增强一些功能而又不改变源代码(例如事务控制、日志等),这时需要一个ProxyHandler类它实现了InvocationHandler接口,在这个类的invoke方法中处理业务

 

  public class ProxyHandlerimplements InvocationHandler {

 

    private peoplepe;

    public ProxyHandler(people p)

    {

      pe=p;

    }

 

 

@Override

    public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

    before();

    method.invoke(pe,null);   

    after();

 

    //这个method的方法就是你要增强的类中eat();方法了。

     注意这个methodinvoke,是method类的invokepe, null

     方法,意思是掉用pe这个类的method方法。

    return null;

}

 

    public void before()

    {

        System.out.println("吃饭前洗手!");

      }


     public void after()

     {

        System.out.println("吃饭后刷碗!");

     }

}

 

 

 

写个测试类:

    public static void main(String[] args)throws IOException {

 

     people p=(people) Proxy.newProxyInstance(people.class.getClassLoader(),new Class[]           {people.class},new ProxyHandler(new zhangsan()));

      

   p.eat();

}

 

现在这个 p.eat();怎么就可以调用ProxyHandler类里的invoke();从而达到代理目的呢?

  

    

1.首先 Proxy.newProxyInstance(people.class.getClassLoader(),new    

         Class[]{people.class},new ProxyHandler(new zhangsan()));

   这个方法干了什么?它是在内存中生成了一个$Proxy0.class类。

 

接下来看看这个类:

 

   import DynamicProxy.people;

   import java.lang.reflect.InvocationHandler;

   import java.lang.reflect.Method;

   import java.lang.reflect.Proxy;

   import java.lang.reflect.UndeclaredThrowableException;

   import java.util.List;

 

   public final class $Proxy0 extends Proxy

      implements people      

    //这个类继承了Proxy类并且实现了people接口,这个people接口就是Proxy.newProxyInstance(people.class.getClassLoader(),      new Class[] {people.class},new ProxyHandler(new zhangsan()));  传的接口数组

  {

      private static Method m1;

      private static Method m3;

      private static Method m0;

      private static Method m4;

      private static Method m2;

 

     static

    {

       try

     {

       m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object")         });

       m3 = Class.forName("DynamicProxy.people").getMethod("eat", new Class[0]);

             m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);

              m4 = Class.forName("DynamicProxy.people").getMethod("sport", new Class[0]);

      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);

       return;

     }

     catch (NoSuchMethodException localNoSuchMethodException)

     {

       throw new NoSuchMethodError(localNoSuchMethodException.getMessage());

     }

     catch (ClassNotFoundException localClassNotFoundException)

     {

     throw new NoClassDefFoundError(localClassNotFoundException.getMessage());

     }

  }

 

   //这里的m3,m4就是people接口里的函数了

 


     public $Proxy0(InvocationHandler paramInvocationHandler)

        throws

     {

       super(paramInvocationHandler);

     }

 

      public final boolean equals(Object paramObject)

        throws

    {

      try

      {

        return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();

       }

        catch (Error|RuntimeException localError)

      {

       throw localError;

      }

       catch (Throwable localThrowable)

      {

        throw new UndeclaredThrowableException(localThrowable);

      }

    }

 

 

               //这里当调用 p.eat();  就会调用 $Proxy0的这个eat()方法了

                 即:    return (List)this.h.invoke(this, m3, null);这个语句

          而这个h$Proxy0这个父类Proxy类中是protected InvocationHandlerh;

         也就是 Proxy.newProxyInstance(people.class.getClassLoader(),new Class[]{people.class},new ProxyHandler(              new zhangsan()));中我们传入的代理类ProxyHandler,这样就会调到我们用以增强函数的那个invoke()方法了

 

 

     public final List eat()

      throws

    {

      try

      {

         return (List)this.h.invoke(this, m3, null);

      }

     catch (Error|RuntimeException localError)

     {

       throw localError;

     }

     catch (Throwable localThrowable)

     {

       throw new UndeclaredThrowableException(localThrowable);

     }

   }

 



   public final int hashCode()

     throws

   {

     try

     {

       return ((Integer)this.h.invoke(this, m0, null)).intValue();

     }

     catch (Error|RuntimeException localError)

     {

       throw localError;

     }

     catch (Throwable localThrowable)

     {

       throw new UndeclaredThrowableException(localThrowable);

     }

  }

 

   public final void sport()

     throws

  {

     try

     {

       this.h.invoke(this, m4, null);

       return;

     }

     catch (Error|RuntimeException localError)

     {

       throw localError;

     }

     catch (Throwable localThrowable)

     {

       throw new UndeclaredThrowableException(localThrowable);

     }

   }

 

   public final String toString()

     throws

   {

     try

     {

       return (String)this.h.invoke(this, m2, null);

     }

     catch (Error|RuntimeException localError)

     {

       throw localError;

     }

     catch (Throwable localThrowable)

     {

     throw new UndeclaredThrowableException(localThrowable);

     }

   }


 

}

 

   

 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值