黑马程序员---------动态代理

来源:互联网 发布:淘宝乞丐裤露鸟截图 编辑:程序博客网 时间:2024/05/16 19:50

----------------------android培训java培训、期待与您交流! --------------------

代理

 

代理的定义:代理就是为其他目标类来提供一种代理以控制对这个对象的访问。
代理模式的主要作用是为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。代理模式的思想是为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信。
代理创建的前提就是有能实现一个共同的接口,这个接口中有共同的方法。


1、使用反射生产动态代理


java为我们提供了一个Proxy类和一个InvocationHandle接口,通过使用这个类和接口就可以生成动态代理。
Proxy为我们提供的静态方法可以创建动态代理类。方法如下:
static Class<?>  getProxyClass(ClassLoader loader,Class<?>  interface):创建一个动态代理类所对应的class对象,该代理类将实现interface所指定的多个接口。
static Object newProxyInstance(ClassLoader loader,Class<?>[] interface,InvocationHandler  h):直接创建动态代理类的对象,该代理对象的实现类实现了interface所指定的系列接口,执行代理对象的每个方法都会被替换成执行InvocationHandler对象的invoke方法。
例如:我们使用代理类的class对象来创建代理类的实例对象。

package ProxyTest;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.lang.reflect.Type;import java.util.ArrayList;import java.util.Collection;public class ProxyAsInstance { /**  * 使用代理的class对象产生代理类的实例对象  */ public static void main(String[] args)throws Exception {  Class clazzProxy=Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);  Constructor[] constructors=clazzProxy.getConstructors();  for(Constructor constructor:constructors){   System.out.println(constructor);   StringBuilder sb=new StringBuilder(constructor.getName());   sb.append('(');   Type[] paTypes=constructor.getParameterTypes();   for(Type  paType:paTypes){    sb.append(paType.toString()+',');   }   if(sb.length()>0)    sb.deleteCharAt(sb.length()-1);   sb.append(')');   System.out.println(sb.toString());   }  System.out.println("method   is  coming");  Method[] methods=clazzProxy.getMethods();  for(Method  method:methods){   StringBuilder sb=new StringBuilder(method.getName());   sb.append('(');   Type[] mTypes=method.getParameterTypes();   for(Type mType:mTypes){    sb.append(mType.toString()+',');   }   if(sb.length()>0)    sb.deleteCharAt(sb.length()-1);   sb.append(')');   System.out.println(sb.toString()); if(sb.length()>0)    sb.deleteCharAt(sb.length()-1);   sb.append(')');   System.out.println(sb.toString());   }  System.out.println("Instance  is  coming");  //获得代理的构造函数  Constructor constructor=clazzProxy.getConstructor(InvocationHandler.class);  //创建代理的实例对象  Collection proxyInstance=(Collection)constructor.newInstance(new InvocationHandler(){   ArrayList target=new ArrayList();   public Object invoke(Object proxy, Method method, Object[] args)     throws Throwable {   Object obj=method.invoke(target, args);   //上面添加的必须是代理的目标,---target,再添加proxy就会死循环   return obj;   }});  proxyInstance.add("hellow");  proxyInstance.add("yes");  proxyInstance.add("good");  System.out.println(proxyInstance.size()); }}


打印的结果就是如下:


public $Proxy0(java.lang.reflect.InvocationHandler)$Proxy0(interface java.lang.reflect.InvocationHandler)method   is  cominghashCode)hashCode)equals(class java.lang.Object)equals(class java.lang.Object)toString)toString)add(class java.lang.Object)add(class java.lang.Object)contains(class java.lang.Object)contains(class java.lang.Object)isEmpty)isEmpty)size)size)toArray)toArray)toArray(class [Ljava.lang.Object;)toArray(class [Ljava.lang.Object;)addAll(interface java.util.Collection)addAll(interface java.util.Collection)iterator)iterator)remove(class java.lang.Object)remove(class java.lang.Object)clear)clear)containsAll(interface java.util.Collection)containsAll(interface java.util.Collection)removeAll(interface java.util.Collection)removeAll(interface java.util.Collection)retainAll(interface java.util.Collection)retainAll(interface java.util.Collection)isProxyClass(class java.lang.Class)isProxyClass(class java.lang.Class)getProxyClass(class java.lang.ClassLoader,class [Ljava.lang.Class;)getProxyClass(class java.lang.ClassLoader,class [Ljava.lang.Class;)getInvocationHandler(class java.lang.Object)getInvocationHandler(class java.lang.Object)newProxyInstance(class java.lang.ClassLoader,class [Ljava.lang.Class;,interface java.lang.reflect.InvocationHandler)newProxyInstance(class java.lang.ClassLoader,class [Ljava.lang.Class;,interface java.lang.reflect.InvocationHandler)getClass)getClass)notify)notify)notifyAll)notifyAll)wait(long,int)wait(long,int)wait)wait)wait(long)wait(long)Instance  is  coming3


总结:通过以上的验证,我们得知:在运用代理实例对象的方法的时候,他时间调用的就是InvocationHandler的invoke方法。


2、动态代理和AOP


AOP----面向切面编程的思想就是为了在不同对象的代码中能够执行自己方法的同时还能加入额外的信息,这部分额外的信息不想已硬编码的形式体现,所有就有了动态代理对象的产生去执行那部分需要经常变动的代码。可以再方法前也可以在方法后。


2.1 首先,我们创建一个接口,让子类去实现它。

package ProxyTest;public interface Dog { void shou(); void sing();}


2.2 创建一个被代理的类

package ProxyTest;public class SuperDog implements  Dog{  public void shou() {   System.out.println("hellow"); } public void sing() {  System.out.println("I  am a super dog"); } }


2.3 创建一个对象,就是需要嵌入被代理对象其中须执行的方法。

package ProxyTest;public class NoFunctionDog { public void method1() {  System.out.println("I want to sleep"); } public void method2(){  System.out.println("I want to study java"); }}


2.4 创建InvocationHandler子类并复写invoke方法-----因为动态代理对象执行方法时候,就是在执行invoke方法

package ProxyTest;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class MyInvocationHandler implements InvocationHandler{ private Object target;  public void setTarget(Object target) {  this.target = target; }//动态代理对象的所有方法的时候,都会调用一下方法。 public Object invoke(Object proxy, Method method, Object[] args)   throws Throwable {   NoFunctionDog ng=new NoFunctionDog();   ng.method1();     Object obj= method.invoke(target, args);    ng.method2();   return obj; }}


2.5 创建Proxy对象产生工厂,他的getProxyObject方法就是产生代理对象

package ProxyTest;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class MyProxyFactory { //这个类就是用来产生动态代理对象的  public static Object getProxyObject(Object target)throws Exception {  MyInvocationHandler mhl=new MyInvocationHandler();  mhl.setTarget(target);//将target设置成被代理的对象  Object obj=Proxy.newProxyInstance(target.getClass().getClassLoader(),    target.getClass().getInterfaces(), mhl);  return obj; }}


2.6 测试

package ProxyTest;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class MyProxyFactory { //这个类就是用来产生动态代理对象的  public static Object getProxyObject(Object target)throws Exception {  MyInvocationHandler mhl=new MyInvocationHandler();  mhl.setTarget(target);//将target设置成被代理的对象  Object obj=Proxy.newProxyInstance(target.getClass().getClassLoader(),    target.getClass().getInterfaces(), mhl);  return obj; }}


执行结果如下:

I want to sleepI  am a super dogI want to study javaI want to sleephellowI want to study java


3、总结


这种动态的代理在AOP里面被称为AOP代理,他包含了可替代目标对象,以及代理目标对象的全部方法。相信在以后的学习过程中,我们还会用到。


----------------------android培训java培训、期待与您交流! --------------------