Java编程思想读书笔记--第14章类型信息
7.动态代理
代理是基本的设计模式之一,它是你为了提供额外的或不同的操作,而插入的用来代替“实际”对象的对象。这些操作通常涉及与“实际”对象的通信,因此代理通常充当着中间人的角色。
什么是代理模式?
代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。
代理模式有什么好处?
在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式一般涉及到的角色有:
抽象角色:声明真实对象和代理对象的共同接口,这样一来在任何可以使用目标对象的地方都可以使用代理对象。
代理角色:代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象提供一个与目标对象相同的接口,以便可以在任何时候替代目标对象。代理对象通常在客户端调用传递给目标对象之前或之后,执行某个操作,而不是单纯地将调用传递给目标对象,同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:定义了代理对象所代表的目标对象,代理角色所代表的真实对象,是我们最终要引用的对象,定义了代理对象所代表的目标对象。
public interface AbstractObject {
public void doSomething();
}
public class RealObject implements AbstractObject {
public void doSomething() {
System.out.println("doSomething");
}
}
public class ProxyObject implements AbstractObject{
private AbstractObject abstractObject;
public ProxyObject(AbstractObject abstractObject){
this.abstractObject = abstractObject;
}
public void doSomething() {
System.out.println("Proxy doSomething");
abstractObject.doSomething();
}
}
public class PorxyDemo {
public static void main(String[] args) {
new ProxyObject(new RealObject()).doSomething();
}
}
Java的动态代理比代理的思想更向前迈进了一步,代理类是在程序运行时动态生成的。
动态代理的优势
动态代理的优势在于可以方便的对代理类的函数进行统一的处理,而不用修改代理类的每个函数。
在使用动态代理时,我们需要定义一个位于代理类与委托类之间的中介类,这个中介类被要求实现InvocationHandler接口,这个接口的定义如下:
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}
当我们调用代理类对象的方法时,这个调用会转送到invoke方法中,代理类对象作为proxy参数传入,参数method标识了我们具体调用的是代理类的哪个方法,args为这个方法的参数。这样一来,我们对代理类中的所有方法的调用都会变成对invoke的调用,这样我们可以在invoke方法中添加统一的处理逻辑(也可以根据method参数对不同的代理类方法做不同的处理)。我们调用Proxy类的newProxyInstance方法获取一个代理类实例,这个代理类实现了指定的接口并且会把方法调用分发到指定的调用处理器。
public interface AbstractObject {
public void doSomething();
public void doOtherThing();
}
public class RealObject implements AbstractObject {
public void doSomething() {
System.out.println("doSomething");
}
public void doOtherThing() {
System.out.println("doOtherThing");
}
}
public class DynamicProxyHandler implements InvocationHandler{
private AbstractObject abstractObject;
public DynamicProxyHandler(AbstractObject abstractObject) {
this.abstractObject = abstractObject;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("before");
Object result = method.invoke(abstractObject, args);
System.out.println("after");
return result;
}
}
public class DynamicProxyDemo {
public static void main(String[] args) {
DynamicProxyHandler dynamicProxyHandler = new DynamicProxyHandler(new RealObject());
AbstractObject proxy = (AbstractObject) Proxy.newProxyInstance(AbstractObject.class.getClassLoader(), new Class[]{AbstractObject.class}, dynamicProxyHandler);
proxy.doSomething();
proxy.doOtherThing();
}
}
动态代理小结
首先通过newProxyInstance方法获取代理类实例,而后通过这个代理类实例调用代理类的方法,该调用会被转发给中介类的invoke方法,在invoke方法中我们调用委托类的相应方法,并且可以添加自己的处理逻辑。
Java编程思想读书笔记--第14章类型信息的更多相关文章
- Java编程思想读书笔记_第二章
java对于将一个较大作用域的变量“隐藏”的场景会有保护:编译告警.比如: int x = 5; { int x = 6; } 但是对于类中方法的局部变量和类成员变量确是可以重名的,比如 class ...
- Java编程思想读书笔记--第21章并发
1.基本的线程机制 定义任务 public class LiftOff implements Runnable{ protected int countDown = 10; private stati ...
- JAVA编程思想读书笔记(三)--RTTI
接上篇JAVA编程思想读书笔记(二) 第十一章 运行期类型判定 No1: 对于作为程序一部分的每个类,它们都有一个Class对象.换言之,每次写一个新类时,同时也会创建一个Class对象(更恰当的说, ...
- JAVA编程思想读书笔记(五)--多线程
接上篇JAVA编程思想读书笔记(四)--对象的克隆 No1: daemon Thread(守护线程) 参考http://blog.csdn.net/pony_maggie/article/detail ...
- JAVA编程思想读书笔记(四)--对象的克隆
接上篇JAVA编程思想读书笔记(三)--RTTI No1: 类的克隆 public class MyObject implements Cloneable { int i; public MyObje ...
- JAVA编程思想读书笔记(二)--容器
接上篇JAVA编程思想读书笔记(一) 第八章.对象的容纳 No1: java提供了四种类型的集合类:Vector(矢量).BitSet(位集).Stack(堆栈).Hashtable(散列表) No2 ...
- Java编程思想读书笔记(一)【对象导论】
2018年1月7日15:45:58 前言 作为学习Java语言的经典之作<Java编程思想>,常常被人提起.虽然这本书出版十年有余,但是内容还是很给力的.很多人说这本书不是很适合初学者,我 ...
- [Java编程思想-学习笔记]第3章 操作符
3.1 更简单的打印语句 学习编程语言的通许遇到的第一个程序无非打印"Hello, world"了,然而在Java中要写成 System.out.println("He ...
- Java编程思想读书笔记之内部类
现在是够懒得了,放假的时候就想把这篇笔记写出来,一直拖到现在,最近在读<Java编程思想>,我想会做不止这一篇笔记,因为之前面试的时候总会问道一些内部类的问题,那这本书的笔记就从内部类开始 ...
随机推荐
- [一位菜鸟的COCOS-2D编程之路]精灵表单的制作以及简易动画的生成
1.第一步:使用Zwoptex 制作精灵表单 2.制作的表单的名称为 cocos2Dpng,cocos2D.plist: 3.精灵的动画效果 主要分为五部分. // on "init&quo ...
- selenium 自动化测试面试题及答案
写在开始: 这些问题和答案,都是自己在网上找的,整理的,有任何问题,概不负责.主要感谢博主Ray,http://www.cnblogs.com/tsbc/p/4922368.html 1.seleni ...
- SQLite使用教程3 数据类型
http://www.runoob.com/sqlite/sqlite-data-types.html SQLite 数据类型 SQLite 数据类型是一个用来指定任何对象的数据类型的属性.SQLit ...
- 修改 suse 上的postfix 的日志路径
刚刚搭建的邮件服务器,没过多久硬盘就爆满了,不得已移动存储,包括日志. 移动存储灰常简单,查找 /etc/postfix/main.cf 中的 data_directory / base_direct ...
- 【转】来自《轻松scrum之旅》的敏捷开发总结
敏捷开发的核心价值观是,软件开发最重要的是给用户提供有价值的.可以工作的软件.如何保证提供有价值的软件,是通过反馈机制来完成的.这一点,我们体会很深.自从采用敏捷开发以后,我们比以前更有意识地希望得到 ...
- mysqldump when doing LOCK TABLES问题
今天打出表结构和数据遇到问题. mysqldump -udbuser -p dbname > dbname.sql 保存信息为: when doing LOCK TABLES 解决方法: mys ...
- Ubuntu Linux下如何配置Android开发环境
下载和安装Win7系统Android开发环境中讲了怎样在Win7系统中安装Android开发环境,那么怎样在Linux系统中配置Android开发环境呢?本篇文章就将演示如何使用Eclipse.And ...
- 兼容:判断 iframe 是否加载完成
判断 iframe 是否加载完成其实与 判断 JavaScript 文件是否加载完成 采用的方法很类似 var iframe = document.createElement("iframe ...
- android学习日记27--Dialog使用及其设计模式
1.Dialog概述 对话框一般是一个出现在当前Activity之上的一个小窗口,处于下面的Activity失去焦点, 对话框接受所有的用户交互. 对话框一般用于提示信息和与当前应用程序直接相关的小功 ...
- 读写锁ReaderWriterLockSlim
读写锁的概念很简单,允许多个线程同时获取读锁,但同一时间只允许一个线程获得写锁,因此也称作共享-独占锁. 某些场合下,对一个对象的读取次数远远大于修改次数,如果只是简单的用lock方式加锁,则会影响读 ...