网站首页 网站导航 课程中心
新闻中心
您所在的位置:Java培训 > 新闻中心 > Java的动态代理机制详解(二)

Java的动态代理机制详解(二)

来源:中软卓越 日期:2017-05-22 13:55 人气:
  Java的动态代理机制详解(二)
       上篇中软卓越Java培训已经讲了一部分,最后,来看看我们的Client类:
  
  publicclassClient{publicstaticvoidmain(String[]args){//我们要代理的真实对象SubjectrealSubject=newRealSubject();//我们要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法的InvocationHandlerhandler=newDynamicProxy(realSubject);/**通过Proxy的newProxyInstance方法来创建我们的代理对象,我们来看看其三个参数*第一个参数handler.getClass().getClassLoader(),我们这里使用handler这个类的ClassLoader对象来加载我们的代理对象*第二个参数realSubject.getClass().getInterfaces(),我们这里为代理对象提供的接口是真实对象所实行的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了*第三个参数handler,我们这里将这个代理对象关联到了上方的InvocationHandler这个对象上*/Subjectsubject=(Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(),realSubject.getClass().getInterfaces(),handler);System.out.println(subject.getClass().getName());subject.rent();subject.hello("world");}}
  
  我们先来看看控制台的输出:
  
  $Proxy0beforerenthouseMethod:publicabstractvoidcom.xiaoluo.dynamicproxy.Subject.rent()IwanttorentmyhouseafterrenthousebeforerenthouseMethod:publicabstractvoidcom.xiaoluo.dynamicproxy.Subject.hello(java.lang.String)hello:worldafterrenthouse
  
  我们首先来看看$Proxy0这东西,我们看到,这个东西是由System.out.println(subject.getClass().getName());这条语句打印出来的,那么为什么我们返回的这个代理对象的类名是这样的呢?
  
  Subjectsubject=(Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(),realSubject.getClass().getInterfaces(),handler);
  
  可能我以为返回的这个代理对象会是Subject类型的对象,或者是InvocationHandler的对象,结果却不是,首先我们解释一下为什么我们这里可以将其转化为Subject类型的对象?原因就是在newProxyInstance这个方法的第二个参数上,我们给这个代理对象提供了一组什么接口,那么我这个代理对象就会实现了这组接口,这个时候我们当然可以将这个代理对象强制类型转化为这组接口中的任意一个,因为这里的接口是Subject类型,所以就可以将其转化为Subject类型了。
  
  同时我们一定要记住,通过Proxy.newProxyInstance创建的代理对象是在jvm运行时动态生成的一个对象,它并不是我们的InvocationHandler类型,也不是我们定义的那组接口的类型,而是在运行是动态生成的一个对象,并且命名方式都是这样的形式,以$开头,proxy为中,最后一个数字表示对象的标号。
  
  接着我们来看看这两句
  
  subject.rent();subject.hello(“world”);
  
  这里是通过代理对象来调用实现的那种接口中的方法,这个时候程序就会跳转到由这个代理对象关联到的handler中的invoke方法去执行,而我们的这个handler对象又接受了一个RealSubject类型的参数,表示我要代理的就是这个真实对象,所以此时就会调用handler中的invoke方法去执行:
  
  publicObjectinvoke(Objectobject,Methodmethod,Object[]args)throwsThrowable{//在代理真实对象前我们可以添加一些自己的操作System.out.println("beforerenthouse");System.out.println("Method:"+method);//当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用method.invoke(subject,args);//在代理真实对象后我们也可以添加一些自己的操作System.out.println("afterrenthouse");returnnull;}
  
  我们看到,在真正通过代理对象来调用真实对象的方法的时候,我们可以在该方法前后添加自己的一些操作,同时我们看到我们的这个method对象是这样的:
  
  publicabstractvoidcom.xiaoluo.dynamicproxy.Subject.rent()publicabstractvoidcom.xiaoluo.dynamicproxy.Subject.hello(java.lang.String)
  
  正好就是我们的Subject接口中的两个方法,这也就证明了当我通过代理对象来调用方法的时候,起实际就是委托由其关联到的handler对象的invoke方法中来调用,并不是自己来真实调用,而是通过代理的方式来调用的。
  
  这就是我们的java动态代理机制。
  
  中软卓越本篇随笔详细的讲解了java中的动态代理机制,这个知识点非常非常的重要,包括我们Spring的AOP其就是通过动态代理的机制实现的,所以我们必须要好好的理解动态代理的机制。
  
  中软卓越以Java课程作为主打课程之一,课程内容全部提炼自企业一线岗位实际工作经验和能力标准;课程内容来自于企业岗位需求又高于企业岗位任职标准;不仅满足应聘时工作需求,又着眼于未来职业发展需要。课程体系严密,围绕企业需求,以实战项目导入教学体系;模块课程完整,每个模块对应一类岗位,将所有岗位能力对应到各个模块;课程内容全面,所有课程内容吸纳最新Java知识,全面覆盖了各个知识点,中软卓越用技术改变你的未来,用责任帮你谱写人生!

营业执照 版权所有©Copyright 2008-2017,北京中软国际教育科技股份有限公司, All Rights Reserved. ICP备案号:京ICP备14058756号-2

| | 分类导航 | 关于我们