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

java代理机制java代理

3天前CN2资讯

一、一般情况下处理业务的方法

只要实现处理业务逻辑的代码就行了。比如下面的DoSomething中的doSomething()方法为模拟处理业务的代码。客户端只要调用DoSomething中doSomething()方法即可

处理业务代码DoSomething.java

1 import java.util.Random; 2 3 public class DoSomething { 4 public void doSomething(){ 5 System.out.println("doing something..."); 6 try { 7 Thread.sleep((new Random().nextInt(2000))); //模拟处理需要时间 8 } catch (InterruptedException e) { 9 e.printStackTrace(); 10 } 11 } 12 }

客户端调用代码Client.java

1 public class Client { 2 public static void main(String args[]){ 3 DoSomething doSomething = new DoSomething(); 4 doSomething.doSomething(); 5 } 6 }

现在需要在控制台输出这个方法的执行时间,该怎么实现呢

直接在doSomething()方法中添加开始时间和结束时间的代码,输出执行时间。DoSomething.java代码如下所示

1 import java.util.Random; 2 3 public class DoSomething { 4 public void doSomething(){ 5 long startTime = System.currentTimeMillis(); 6 System.out.println("doing something..."); 7 try { 8 Thread.sleep((new Random().nextInt(2000))); //模拟处理需要时间 9 } catch (InterruptedException e) { 10 e.printStackTrace(); 11 } 12 long endTime = System.currentTimeMillis(); 13 14 System.out.println("执行任务耗时:" + (endTime - startTime) + "毫秒"); 15 } 16 }

从输出可以看到功能已经实现。

但是,这样代码耦合度会增加。如果我不需要输出执行时间,每一个方法都需要去修改。不利于代码重用

二、设计模式纸代理模式Proxy

上面为什么代码耦合度会高呢,主要是业务逻辑代码和分支代码混在一起。把这两个分开,即可解耦。这里可以利用设计模式里面的代理模式

下面是代理模式的UML图

从图中可以看出代理模式和实际业务处理共同实现了一个接口,这样在客户端就可以面向接口编程了。在ProxySubject中有RealSubject的引用,在代理中可以调用RealSubject的方法。同时,可以在调用RealSubject的方法时候进行其他处理。比如前面所说的计算所耗费的时间等...

将上面的的代码按照Proxy模式实现。先定义一个接口,接口中为RealSubject中所有的方法。这里就是上面DoSomething中的doSomething()方法。代理类和RealSubject分别实现这个接口。代理类添加RealSubject的引用。在客户端使用代理。

代码如下所示

IDoSomething.java对应上图中的Subject

1 public interface IDoSomething { 2 public void doSomething(); 3 }

DoSomething.java对应上图中的RealSubject

1 public class DoSomething implements IDoSomething { 2 3 @Override 4 public void doSomething() { 5 System.out.println("doing something..."); 6 try { 7 Thread.sleep((new Random().nextInt(2000))); //模拟处理需要时间 8 } catch (InterruptedException e) { 9 e.printStackTrace(); 10 } 11 12 } 13 14 }

Proxy.java对应上图中的ProxySubject

1 public class Proxy implements IDoSomething { 2 IDoSomething doSomething = new DoSomething(); //实际处理类引用 3 4 5 @Override 6 public void doSomething() { 7 long startTime = System.currentTimeMillis(); 8 doSomething.doSomething(); //处理业务的方法 9 long endTime = System.currentTimeMillis(); 10 11 System.out.println("执行任务耗时:" + (endTime - startTime) + "毫秒"); 12 13 } 14 15 }

Client.java

1 public class Client { 2 3 public static void main(String[] args) { 4 IDoSomething doSomeThingProxy = new Proxy(); 5 doSomeThingProxy.doSomething(); //调用代理类的方法 6 } 7 8 }

这样就实现了两种代码的分离,降低代码耦合度

但是这样也有缺点。这里实现的Subject类型的代理,如果我有很多种类型呢。是不是需要为每一种类型写代理呢。java代理机制提供了一种解决方案。动态代理机制

三、java代理机制

首先,先看一下java代理机制的UML图

这里没有画出Client端。从上图中可以看出这里Proxy中没有直接引用RealSubject,而是引用了ProxyInHand对象。ProxyInHand中引用了RealSubject方法。(这里只是从UML中看出来的)

这里先直接给出实现步骤

首先让我们来了解一下如何使用 Java 动态代理。具体有如下四步骤:

  • 通过实现 InvocationHandler 接口创建自己的调用处理器;
  • 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
  • 通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
  • 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。
  • 清单 3. 动态代理对象创建过程
    // InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发 // 其内部通常包含指向委托类实例的引用,用于真正执行分派转发过来的方法调用 InvocationHandler handler = new InvocationHandlerImpl(..); // 通过 Proxy 为包括 Interface 接口在内的一组接口动态创建代理类的类对象 Class clazz = Proxy.getProxyClass(classLoader, new Class[] { Interface.class, ... }); // 通过反射从生成的类对象获得构造函数对象 Constructor constructor = clazz.getConstructor(new Class[] { InvocationHandler.class }); // 通过构造函数对象创建动态代理类实例 Interface Proxy = (Interface)constructor.newInstance(new Object[] { handler });

    实际使用过程更加简单,因为 Proxy 的静态方法 newProxyInstance 已经为我们封装了步骤 2 到步骤 4 的过程,所以简化后的过程如下

    清单 4. 简化的动态代理对象创建过程
    // InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发 InvocationHandler handler = new InvocationHandlerImpl(..); // 通过 Proxy 直接创建动态代理类实例 Interface proxy = (Interface)Proxy.newProxyInstance( classLoader, new Class[] { Interface.class }, handler );

    个人理解,先写好处理业务逻辑的代码RealSubject,实现InvocationHandler接口(java api) InvocationHandlerImpl,在InvocationHandlerImpl中调用RealSubject处理方法。通过

    Interface proxy = (Interface)Proxy.newProxyInstance( classLoader, new Class[] { Interface.class }, handler );方法生成代理类

    ·

      你可能想看:

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

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

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

      分享给朋友:

      “java代理机制java代理” 的相关文章

      服务器租赁指南:如何选择适合的云服务和价格

      对于很多企业和个人用户来说,服务器租赁是一个非常实用的选择。简单来说,服务器租赁就是用户向服务器提供商支付费用,然后获得在一定时间内使用服务器的权利。这样一来,用户就无需花费时间和金钱去购买和维护物理服务器,可以迅速开始在线业务。 当我第一次接触服务器租赁时,发现这一服务的便利性令我十分惊讶。传统的...

      VPS优惠活动解析:如何选择最划算的虚拟专用服务器方案

      在当今互联网环境中,VPS(虚拟专用服务器)为企业和个人用户提供了灵活、高效的解决方案。随着云计算的普及,VPS逐渐成为许多用户的首选。不管是建站、开发、还是日常的数据处理,选择一款合适的VPS至关重要。而在不同的VPS服务提供商中,优惠活动往往能让用户以更实惠的价格体验高质量的服务。 什么是VPS...

      AWS VPS Free: 如何利用AWS Free Tier免费服务轻松构建云计算项目

      当我第一次接触AWS (亚马逊网络服务) 的时候,最吸引我的就是他们提供的各种免费的VPS服务。AWS的VPS免费服务实际上是一种叫做AWS Free Tier的计划,它允许用户在一定条件下使用AWS的多种服务而无需支付费用。这项计划的意义在于,它为刚入门的开发者和小型企业提供了一个绝佳的机会,能够...

      Virmach Coupon 让您轻松获取高性价比的VPS服务

      在今天的网络世界中,寻找高性价比的虚拟专用服务器(VPS)和云托管服务是一项挑战。Virmach正是在这样的背景下脱颖而出。总部位于加利福尼亚州洛杉矶的Virmach,以其多样的服务和全球级的数据中心而闻名,满足了不同用户的需求。无论是新手小白还是经验丰富的开发者,Virmach都能提供适合他们的解...

      搬瓦工查看流量使用的最佳方法与管理策略

      在使用搬瓦工(BandwagonHost)这家VPS提供商时,了解流量的相关信息是非常重要的。搬瓦工的流量套餐设计十分灵活,满足了不同用户的需求。每个VPS方案都设有流量限制,比如每月500GB或1TB,这些限制会直接影响到我们如何使用这些资源。用户在选择方案时,应该充分考虑自己的日常使用习惯,以便...

      如何使用Windows网络诊断工具查找服务器地址和解决网络问题

      在当今这个网络无处不在的时代,能够快速诊断网络问题已变得尤为重要。作为Windows用户,我们的设备中自带了一个非常实用的工具——Windows网络诊断工具。说到这个工具,许多人可能不太了解它的具体功能和用途。 Windows网络诊断工具是一个集成在Windows操作系统中的应用,专门用于帮助用户识...