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

----------------------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  coming
hashCode)
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  coming
3


总结:通过以上的验证,我们得知:在运用代理实例对象的方法的时候,他时间调用的就是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 sleep
I  am a super dog
I want to study java
I want to sleep
hellow
I want to study java


3、总结


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


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

 

 

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值