当前位置:首页 > CN2资讯 > 正文内容

jdk动态代理(转)jdk动态代理

2天前CN2资讯


一旦这样绑定后,那么在进入代理对象方法调用的时候就会到HelloServiceProxy的invoke方法上,invoke方法有三个参数:第一个proxy是代理对象,第二个是当前调用那个方法,第三个是方法的参数。

 

 

2、JDK动态代理

这个动态代理还是不好理解的,我们先用一张图来表达它:

 

 

好,它的意义是在我们访问一个对象的时候,动态代理可以给我们生成一个代理对象【占位】,它的作用是可以控制【真实对象】的访问。

比方说,你是未成年人,我可能是是去访问你父母,由你父母来代替你访问你,那么你父母就是这个占位,而你就是真实对象。

在JDK动态代理的要求是对象存在接口,所以真正的服务对象必须存在接口。

假设我们现在有这样的一个服务,我给名字它会说: “hello ”+名字。

那么我们先看看这个接口:

 




[java] ​​view plain​​ ​​copy​​

 

 ​​print​​​​?​​

  • public interface HelloService {  
  •       
  •     public void sayHello(String name);  
  •       
  • }  

  • 非常简单的接口,然后我们给出实现类:

     

     




    [java] ​​view plain​​ ​​copy​​

     

     ​​print​​​​?​​

  • public class HelloServiceImpl implements HelloService{  
  •     @Override  
  •     public void sayHello(String name) {  
  •         System.err.println("hello " + name);  
  •     }  
  • }  

  • 好,它实现了这个接口,并且实现了接口的方法。

     

    现在我们要变变,我希望

    在说:hello+name前打印:我准备说hello。

    之后打印:我说过hello了

    如果采用我们的代理对象【占位】显然实现起来非常容易,于是我们首先来生成这个【占位】

     




    [java] ​​view plain​​ ​​copy​​

     

     ​​print​​​​?​​

  • import java.lang.reflect.InvocationHandler;  
  • import java.lang.reflect.Method;  
  • import java.lang.reflect.Proxy;  
  •   
  • public class HelloServiceProxy implements InvocationHandler {  
  •   
  •   
  •     private Object target;    
  •     /**  
  •      * 绑定委托对象并返回一个【代理占位】 
  •      * @param target 真实对象 
  •      * @return  代理对象【占位】 
  •      */    
  •     public  Object bind(Object target, Class[] interfaces) {    
  •         this.target = target;    
  •         //取得代理对象    
  •        <span > return Proxy.newProxyInstance(target.getClass().getClassLoader(),    
  •                 target.getClass().getInterfaces(), this);  </span>  
  •     }    
  •     
  •     @Override    
  •     /** 
  •      * 同过代理对象调用方法首先进入这个方法. 
  •      * @param proxy --代理对象 
  •      * @param method -- 方法,被调用方法. 
  •      * @param args -- 方法的参数 
  •      */  
  •     public Object invoke(Object proxy , Method method, Object[] args) throws Throwable {    
  •         System.err.println("############我是JDK动态代理################");  
  •         Object result = null;    
  •         //反射方法前调用  
  •         System.err.println("我准备说hello。");    
  •         //反射执行方法  相当于调用target.sayHelllo;  
  •         result=method.invoke(target, args);  
  •         //反射方法后调用.  
  •         System.err.println("我说过hello了");    
  •         return result;    
  •     }    
  • }  

  • 这里的bind方法里面有句:




    [java] ​​view plain​​ ​​copy​​

     

     ​​print​​​​?​​

  • Proxy.newProxyInstance(target.getClass().getClassLoader(),    
  •                 target.getClass().getInterfaces(), this);   

  • 它的意义就是生成一个代理对象,这里有三个参数:第一个参数是类加载器,第二个参数是或者对象的接口(代理对象挂在那个接口下),第三个参数this代表当前HelloServiceProxy类,换句话说是使用HelloServiceProxy作为对象的代理。

     

    一旦这样绑定后,那么在进入代理对象方法调用的时候就会到HelloServiceProxy的invoke方法上,invoke方法有三个参数:第一个proxy是代理对象,第二个是当前调用那个方法,第三个是方法的参数。

    比方说,现在HelloServiceImpl对象(obj)用bind方法绑定后,返回其【占位】(proxy),我们在调用proxy.sa6yHello("张三"),那么它就会进入到HelloServiceProxy的invoke()方法。而invoke参数中第一个便是代理对象proxy,方法便是sayHello,参数是"张三"。那么我们就可以通过反射技术调度真实对象的方法。

     

    现在让我们看看​​测试​​代码:

     




    [java] ​​view plain​​ ​​copy​​

     

     ​​print​​​​?​​

  • public class ProxyTest {  
  •       
  •     public static void main(String[] args) {   
  •         HelloServiceProxy proxy = new HelloServiceProxy();  
  •         HelloService service = new HelloServiceImpl();  
  •         //绑定代理对象。  
  •         service = (HelloService) proxy.bind(service, new Class[] {HelloService.class});  
  •         //这里service经过绑定,就会进入invoke方法里面了。  
  •         service.sayHello("张三");  
  •     }  
  • }  
  •    

  • 好,我们运行一下,看一下结果。

     

     




    [plain] ​​view plain​​ ​​copy​​

     

     ​​print​​​​?​​

  • ############我是JDK动态代理################  
  • 我准备说hello。  
  • hello 张三  
  • 我说过hello了  

  • 好了,我们这样就可以看到动态代理。

     

     

    正确的理解反射和动态代理是我们进行MyBATIS底层的基础,尤其是动态代理,如果还不了解务必要多做上面的例子,切实理解好。

     



      你可能想看:

      扫描二维码推送至手机访问。

      版权声明:本文由皇冠云发布,如需转载请注明出处。

      本文链接:https://www.idchg.com/info/24929.html

      分享给朋友:

      “jdk动态代理(转)jdk动态代理” 的相关文章

      韩国VPS推荐:丽萨主机、莱卡云、Kdatacenter对比,低延迟高稳定性选择

      丽萨主机 丽萨主机是一家提供韩国VPS服务的知名提供商,特别适合需要低延迟和高稳定性的用户。他们的机房位于首尔,采用双ISP类型原生IP,确保网络连接的稳定性和速度。对于国内用户来说,丽萨主机的三网直连设计让访问延迟保持在60ms左右,非常流畅。他们还提供了59.43的CN2线路,进一步优化了网络体...

      HostDare VPS主机服务评测:高性价比与用户体验的完美结合

      在与HostDare的互动中,我感受到这家公司在客户支持与用户体验方面的一些亮点和不足。正如我们所知,HostDare是一家致力于提供高性价比VPS主机服务的公司,尤其在针对中国大陆用户的优化上表现突出。虽然服务上有一些待改善之处,但总体而言,它的客户支持体系还是相对高效的。 首先,HostDare...

      内部错误解决指南:快速识别与处理方法

      一说到“内部错误”,我们很多人可能会感到一头雾水。其实,内部错误是指在计算机系统或程序内部发生的那种错误。这类错误通常是由于系统内部的某些故障所造成的,或是程序代码本身的一些问题。如果我们把计算机比作一个庞大的工厂,那么内部错误就像是工厂里机器运转不畅或部件失灵,导致整个生产线出现问题。 理解内部错...

      asmallorange购物体验评测:轻松愉悦的一站式在线购物平台

      在购物的世界里,总有一些品牌以独特的姿态吸引着我们的注意,asmallorange 无疑就是其中之一。它不是一个传统意义上的电商平台,而是一个新颖而富有创意的在线零售商,致力于为顾客提供高质量的产品和服务。这个品牌常常以其个性化的服务和独特的购物体验而受到喜爱,让人不禁好奇它背后的故事。 当我第一次...

      2019年黑五购物攻略:如何获得最大折扣与省钱技巧

      每年的黑色星期五总是让我充满期待,这不仅是购物狂欢的时刻,更是找到好折扣的绝佳机会。在准备迎接2019年的黑五时,我总是觉得提前准备很重要,这样才能在众多商品中寻找最划算的选择。 黑五购物前的准备工作 制定购物清单是我每年都不遗漏的一步。我会集中精力,想想自己真正需要的东西,避免在购物时被诱惑而买到...

      Colocrossing与Racknerd服务器托管服务深度对比分析

      在考量数据中心服务提供商时,Colocrossing总给人以相当的印象。它作为一家知名的服务器托管和数据中心服务提供商,吸引了许多不同规模企业的注意。提供的服务范围从基础的托管服务到高级的管理解决方案,Colocrossing致力于满足各种客户的需求。我的体验使我感受到它不仅关注技术实施,同时也注重...