看了好多关于代理的文章,理解和整理一下。

1、代理的基本构成

  抽象角色:声明真实对象和代理对象的共同接口,这样可在任何使用真实对象的地方都可以使用代理对象。

  代理角色:代理对象内部含有真实对象的引用,从而可以在任何时候操作真实对象。代理对象提供一个与真实对象相同的接口,以便可以在任何时候替代真实对象。代理对象通常在客户端调用传递给真实对象之前或之后,执行某个操作,而不是单纯地将调用传递给真实对象,同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。

  真实角色:即为代理对象所代表的目标对象,代理角色所代表的真实对象,是我们最终要引用的对象。

  下图有三种角色:Subject抽象角色、RealSubject真实角色、Proxy代理角色。其中:Subject角色负责定义RealSubject和Proxy角色应该实现的接口;RealSubject角色用来真正完成业务服务功能;Proxy角色负责将自身的request请求,调用RealSubject对应的request功能来实现业务功能,自己不真正做业务。

2、静态代理

interface Subject//抽象角色
{
public void doSomething();
}
class RealSubject implements Subject//真实角色
{
public void doSomething()
{
System.out.println( "call doSomething()" );
}
}
class SubjectProxy implements Subject//代理角色
{
//代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。
Subject subimpl = new RealSubject();
public void doSomething()
{
System.out.println("before"); //调用目标对象之前可以做相关操作
subimpl.doSomething();
System.out.println("after");//调用目标对象之后可以做相关操作
}
} public class Test
{
public static void main(String[] args) throws Exception
{
Subject sub = new SubjectProxy();
sub.doSomething();
}
}

  可以看到,SubjectProxy实现了Subject接口(和RealSubject实现相同接口),并持有的是Subject接口类型的引用。这样调用的依然是doSomething方法,只是实例化对象的过程改变了,结果来看,代理类SubjectProxy可以自动为我们加上了before和after等我们需要的动作。

  如果将来需要实现一个新的接口,就需要在代理类里再写该接口的实现方法,对导致代理类的代码变得臃肿;另一方面,当需要改变抽象角色接口时,无疑真实角色和代理角色也需要改变。

3、JDK动态代理

interface Subject
{
public void doSomething();
}
class RealSubject implements Subject
{
public void doSomething()
{
System.out.println( "call doSomething()" );
}
}
class ProxyHandler implements InvocationHandler
{
private Object tar;
//绑定委托对象,并返回代理类
public Object bind(Object tar)
{
this.tar = tar;
//绑定该类实现的所有接口,取得代理类
return Proxy.newProxyInstance(tar.getClass().getClassLoader(),
tar.getClass().getInterfaces(),
this);
}
public Object invoke(Object proxy , Method method , Object[] args)throws Throwable//不依赖具体接口实现
{
Object result = null;//被代理的类型为Object基类
//这里就可以进行所谓的AOP编程了
//在调用具体函数方法前,执行功能处理
result = method.invoke(tar,args);
//在调用具体函数方法后,执行功能处理
return result;
}
}
public class Test
{
public static void main(String args[])
{
ProxyHandler proxy = new ProxyHandler();
//绑定该类实现的所有接口
Subject sub = (Subject) proxy.bind(new RealSubject());
sub.doSomething();
}
}

  在调用过程中使用了通用的代理类包装了RealSubject实例,然后调用了Jdk的代理工厂方法实例化了一个具体的代理类。最后调用代理的doSomething方法,还有附加的before、after方法可以被任意复用(只要我们在调用代码处使用这个通用代理类去包装任意想要需要包装的被代理类即可)。当接口改变的时候,虽然被代理类需要改变,但是我们的代理类却不用改变了。这个调用虽然足够灵活,可以动态生成一个具体的代理类,而不用自己显示的创建一个实现具体接口的代理类。

java动态代理、Proxy与InvocationHandler的更多相关文章

  1. java动态代理Proxy

    package com.gz_06; public interface StudentDao { public void login(); public void regist(); } packag ...

  2. java 动态代理 Proxy.newProxyInstance 使用心法

    使用JDk的Proxy类的静态方法newProxyInstance ,让JVM自动生成一个新的类,类中包含了inerfaces参数中的所有方法,每个方法都调用h.invoke 方法       AOP ...

  3. java动态代理--proxy&cglib

    大纲 代理 proxy cglib 小结 一.代理 为什么要用代理?其实就是希望不修改对象的情况下,增强对象. 静态代理: 静态代理模式,需要代理类和目标类实现同一接口,代理类的方法调用目标类的方法, ...

  4. java 动态代理范例 InvocationHandler与Proxy

    java 动态代理范例 InvocationHandler与Proxy,拦截与代理 java.lang.reflect.Proxy,Proxy 提供用于创建动态代理类和实例的静态方法.newProxy ...

  5. java 动态代理深度学习(Proxy,InvocationHandler),含$Proxy0源码

    java 动态代理深度学习, 一.相关类及其方法: java.lang.reflect.Proxy,Proxy 提供用于创建动态代理类和实例的静态方法.newProxyInstance()返回一个指定 ...

  6. Java动态代理一Proxy

    什么是动态代理? 动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实.代理一般会实现它所表示的实际对象的接口.代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际对象实现系统的实际功 ...

  7. 动态代理 Proxy InvocationHandler

      前奏 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 代理类与委托类之间通常 ...

  8. 浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance

    浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance java.lang.reflect.Proxy:该类用于动态生成代理类,只需传入目标接口.目标接口的类加载器以及Inv ...

  9. Java动态代理(一)动态类Proxy的使用

    1.什么是动态代理? 答:动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实.代理一般会实现它所表示的实际对象的接口.代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际对象实现系统 ...

  10. 43、Java动态代理一——动态类Proxy的使用

    1.什么是动态代理? 答:动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实.代理一般会实现它所表示的实际对象的接口.代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际对象实现系统 ...

随机推荐

  1. 开源CMS比较

    PHP-CMS的发展方向:简单,易用,美观  http://www.php-cms.cn/ 看点1,服务器一键安装,鼠标点点就搞定:输入数据库参数,在服务器上点一个按钮就完成全部的安装.简单配置一下网 ...

  2. H3C DCC概念

  3. Python--day72--Django内置的serializers序列化介绍

    序列化 Django内置的serializers def books_json(request): book_list = models.Book.objects.all()[0:10] from d ...

  4. Python--day62--删除出版社

    删除成出版社关键代码:

  5. el-table翻页序号不从1开始(已解决)

    法一:赋值方式(亲测有效) <el-table-column type="index" fixed="left" align="center&q ...

  6. MySQL——修改视图

    修改视图是指修改数据库中存在的视图,当基本表的某些字段发生变化时,可以通过修改视图来保持与基本表的一致性. 1.  用  CREATE  OR  REPLACE   VIEW  语句修改视图 语法格式 ...

  7. ESB总线的核心架构

    根据近期对开源ESB产品的研究,已经对Oracle和Tibco的ESB总线产品的实施经验积累,对ESB总线的核心产品架构有了进一步的清晰认识,将ESB的核心架构整理为上图,上图中看到的内容也是做为一款 ...

  8. H3C根桥的选举

  9. linux 安装一个共享的处理者

    共享中断通过 request_irq 来安装就像不共享的一样, 但是有 2 个不同: SA_SHIRQ 位必须在 flags 参数中指定, 当请求中断时. dev_id 参数必须是独特的. 任何模块地 ...

  10. CSS 兼容问题

    CSS常见兼容性问题总结 浏览器的兼容性问题通常是因为不同的浏览器对不同的代码有不同的解析造成页面显示不统一的情况,这里的浏览器通常指IE 6,7,8,9... Google Firefox Oper ...