所谓代理,其实就是相当于一个中间人,当客户端需要服务端的服务时,不是客户直接去找服务,而是客户先去找代理,告诉代理需要什么服务,然后代理再去服务端找服务,最后将结果返回给客户。

在日常生活中,就拿买火车票来比喻。以前买票,都是需要到火车站去买的,但是有些人距离火车站太远不方便去,来来回回总是很麻烦。于是铁道部就在城市的各个地方增设一个火车票代售点,在这个代售点就可以买票而不用去火车站了。这里,这个代售点就相当于一个代理,可以提供火车站所提供的服务。

下面说说JAVA中的代理

代理的实现又分为静态代理和动态代理,

一.静态代理

静态代理意思就是静态的,不能改变的,客户,服务,代理这三者是已经决定好了的。它的实现需要一个接口和这个接口的实现类。

这个接口就是服务端所提供的服务。

比如下面的代码:

//服务
interface Station{
void sellTickit();
} //服务提供类
class SubStation implements Station{
public void sellTickit(){
System.out.println("卖火车票总站");
}
} //服务代理类
class ProxyStation implements Station{ private Station station = null; public ProxyStation(Station station){
this.station = station;
} public void sellTickit(){
System.out.println("这里是代售点,需要去总站拿票");
station.sellTickit();
System.out.println("已经从总站拿到票"); }
} public class ProxyTest{
//此处调用就相当于客户端
public void static main(String[] args){
Station station = new ProxyStation(new SubStation());
station.sellTickit();
}
} //输出结果:
//这里是代售点,需要去总站拿票
//卖火车票总站
//已经从总站拿到票

从上面代码可以看到,当用户调用sellTickit服务时,并不是直接调用服务类的sellTickit,而是调用代理类的sellTickit,代理类中sellTickit再去调用服务类的方sellTickit来提供服务的。这样,代理类就可以在实际调用服务类的服务时做更多的事情,也可以向客户端屏蔽服务类提供服务的细节。

这就是静态代理,虽然说实现起来比较简单,但是从简单的问题上更容易看清楚本质。代理的本质其实就是代理向客户端屏蔽服务端,并且向客户端提供服务端的部分服务

还是拿上面卖票的例子来说,目前服务提供类只提供了卖票服务,所以代理中也只提供了卖票服务。如果现在,服务提供类增加了退票、改签等服务,那么在代理中,就应该也增加这些服务(当然也可以不增加,这样客户就直接去总站退、改,这里假设代理会提供所有的服务)。理解了代理的本质,再来看看动态代理。

二.动态代理

动态代理的实现又分为JDK动态代理和CGLIB动态代理,这里先只说JDK动态代理。动态就是相对于静态的,代理类并不是一开始就有的,而是动态生成的。

此动态代理同样需要一个接口和此接口的实现类,看如下代码

//服务
interface Station{
void sellTickit();
} //服务提供类
class SubStation implements Station{
public void sellTickit(){
System.out.println("卖火车票总站");
}
} class MyInvocationHandler implements InvocationHandler{ Object target = null;
public MyInvocationHandler(Object obj){
this.target = obj;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("这里是代售点,需要去总站拿票");
Object result = method.invoke(target, args);
System.out.println("已经从总站拿到票");
return result;
}
} public class ProxyTest {
public static void main(String[] args){
SubStation subStation = new SubStation();
Station proxyStation = (Subject) Proxy.newProxyInstance(subStation .getClass().getClassLoader(),
subStation .getClass().getInterfaces(),
new MyInvocationHandler(subStation ));
proxyStation.sellTickit();
}
}

可以看到,原来静态定义的代理类已经没有,产生代理类是使用了Proxy.newProxyInstance方法,此方法接收的三个参数分别为服务提供类的类加载器,服务器提供类的接口和一个代理方法调用处理类

这样看着并不能很好的理解到底发生了什么事情,那么我就在main中的proxyStation.sellTickit()处增加断点来调试。



可以看到,此时proxyStation的值为$Proxy0,这就是动态生成的代理类。其中还是成员变量h,它就是MyInvocationHandler的实例,h.target就是SubStation的实例。

那么如何看到$Proxy0代理类的内容呢?可以参考这边文章,通过反编译出Java代码,我们可以看到动态代理所产生的代理类也很类似静态代理中的代理类,只不过是动态生成的。可以看到$Proxy0中实现了服务接口中的所有方法,在它的方法中,是通过调用MyInvocationHandler.invoke来调用服务提供类的服务的。

MyInvocationHandler.invoke方法中的三个参数: proxy, method, args分别代表了$Proxy0的实例,调用的方法和方法的参数。

Java中的JDK动态代理的更多相关文章

  1. Spring中的JDK动态代理

    Spring中的JDK动态代理 在JDK1.3以后提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.在Sun刚推出动态代理时,还很难想象它有多大的实际用途,现在动态代理是实现AOP的绝好底层 ...

  2. Java学习笔记--JDK动态代理

    1.JDK动态代理     JDK1.3之后,Java提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和 ...

  3. Java设计模式之JDK动态代理原理

    动态代理核心源码实现public Object getProxy() { //jdk 动态代理的使用方式 return Proxy.newProxyInstance( this.getClass(). ...

  4. Java 反射之JDK动态代理

    Proxy提供用于创建动态代理类和代理对象的静态方法,它也是所有动态代理类的父类.如果我们在程序中为一个或多个接口动态地生成实现类,就可以使用Proxy来创建动态代理类:如果需要为一个或多个接口动态的 ...

  5. java jdk动态代理模式举例浅析

    代理模式概述 代理模式是为了提供额外或不同的操作,而插入的用来替代”实际”对象的对象,这些操作涉及到与”实际”对象的通信,因此代理通常充当中间人角色. java中常用的动态代理模式为jdk动态代理和c ...

  6. 静态代理与JDK动态代理

    demo地址: https://github.com/ZbLeaning/leaning 代理: 为其他对象提供一种代理以控制对这个对象的访问.分为静态代理和动态代理.代理模式的目的就是为真实业务对象 ...

  7. 017 Java中的静态代理、JDK动态代理、cglib动态代理

    一.静态代理 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由业务实现类.业务代理类两部分组成.业务实现类负责实现主要的业务方法,业 ...

  8. 深度剖析java中JDK动态代理机制

    https://www.jb51.net/article/110342.htm 本篇文章主要介绍了深度剖析java中JDK动态代理机制 ,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定 ...

  9. Java之美[从菜鸟到高手演练]之JDK动态代理的实现及原理

    Java之美[从菜鸟到高手演练]之JDK动态代理的实现及原理 JDK动态代理的实现及原理 作者:二青 邮箱:xtfggef@gmail.com     微博:http://weibo.com/xtfg ...

随机推荐

  1. Ubuntu14.04安装CMake3.6.3

    准备工作:官网下载cmake-3.6.3.tar.gz(https://cmake.org/download/) 1.解压文件tar -xvf cmake-3.6.3.tar.gz,并修改文件权限ch ...

  2. Azure VM上传小文件

    因为需要传一些脚本到Azure的VM里,有个简单方法可以实现,如下 编辑这个rdp文件 点击确定,连接远程计算机 可以在我的电脑里看到本地硬盘

  3. python学习笔记系列----(七)类

    7.1 python类和相关术语的简介 Python 通过最小的新语法和语义在语言中实现了类. 它是 C++ 或者 Modula-3 语言中类机制的混合.类的大多数重要特性都被完整的保留下来:类继承机 ...

  4. web前端浮动、清浮动问题

    浮动的问题如下一一列举如有考虑不周的欢迎欢迎大家补充: 1.浮动,兼容性问题3px的问题,双边距的问题 在平时工作的过程中,解决3px的问题,一般都是初始化*{margin:0;padding:0px ...

  5. 刷新各ifream当前页,下拉项改变触发事件js,给选中项加背景色js

    <script type="text/javascript" language="javascript"> //刷新框架各页面 function r ...

  6. ExtJS6 TreePanel树节点合上展开显示不同图标

    TreePanel的节点如包含子节点,可在展开/合上时显示不同的图标,增强客户端效果,提高用户体验.非常简单,使用TreePanel的两个事件:beforeitemexpand和beforeitemc ...

  7. SQL Server取datetime的日期部分

    在c#中有个Date属性用于返回日期,其实就是当天0点. DateTime dtNow = DateTime.Now; DateTime dtNow2 = dtNow.Date; Console.Wr ...

  8. IOS随机随学

    1.Objective-C是一种面向对象的语言. 2.Objective-C类声明和实现包括两个部分:接口部分和实现部分. 3.Objective-C中方法不是在“.”运算符,而是采用“[]”运算符. ...

  9. tinyshop框架教程已在腾讯课堂开课

    php就业网简介:www.php91.net,专注于Thinkphp框架教程的php框架学习中心.同时也有小崔老师自学php的教程,与你一起成长哦 同时,php就业网教程部分:http://www.p ...

  10. Django进阶2

    一.ORM操作进阶 ForeignKey关联 示例models from django.db import models # Create your models here. class User(m ...