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编程思想>,我想会做不止这一篇笔记,因为之前面试的时候总会问道一些内部类的问题,那这本书的笔记就从内部类开始 ...
随机推荐
- js-弹出一个新窗口 新窗口自动转接到一个页面然后自动关闭
这个问题.好. 在百度问问找到的:他的做法是打开一个后通过实例对象,再进行一将跳转,最后再将JS里定时将实例对象关闭... 这个问题其实不需要两个页面,只要三行JS代码就能实现,除非你在2.php里面 ...
- Hibernate的BaseDao辅助类
1.BaseDao接口类,该类封装了一些hibernate操作数据库的一些常用的方法,包括分页查询,使用该类极大的简化了hibernate的开发 BaseDao.java package com.kj ...
- Java图片上传压缩处理
所需要的jar包在:\jdk1.7.0_25\jre\lib\rt.jar里面 package util; import java.awt.Image; import java.awt.image.B ...
- Android真机抓屏- Android Screen Monitor
一般运行Android应用程序有两种方式一种是设置Android虚拟设备模拟器,通过Android Virtual Manger进行管理,一种是插入USB数据线直接真机上进行调试,但是如果电脑配置比 ...
- ThinkPHP3.2.3新特性之:数据库设置
ThinkPHP3.2.3版本数据库驱动采用PDO完全重写,配置和使用上面也比之前版本更加灵活和强大,我们来了解下如何使用. 首先,3.2.3的数据库配置信息有所调整,完整的数据库设置包括: /* 数 ...
- KeyTweak 键盘按键功能修改
最近一致再用ThinkPad S3,悲剧的是上翻页和下翻页竟然和方向键在一起,经常按错光标不知道去哪里了. 实在忍受不了,竟然有这样的软件,哈哈. KeyTweak,用起来太方便了
- Android硬件加速
Android从3.0(API Level 11)开始,在绘制View的时候支持硬件加速,充分利用GPU的特性,使得绘制更加平滑,但是会多消耗一些内存. 开启或关闭硬件加速: 由于硬件加速自身并非完美 ...
- ios项目开发(天气预报项目):通过经纬度获取当前城市名称
1 . 在项目里加入� CoreLocation.framework 2 .在 .h 文件输入例如以下: 1.#import <CoreLocation/CLLocation.h> ...
- iOS开发——基本常识篇&各种控件默认高度
各种控件默认高度 1.状态栏 状态栏一般高度为20像素,在打手机或者显示消息时会放大到40像素高,注意,两倍高度的状态栏在好像只能在纵向的模式下使用.如下图 用户可以隐藏状态栏,也可以将状态栏设置 ...
- sql根据表名获取字段及对应说明
SELECT TableName = OBJECT_NAME(c.object_id), ColumnsName = c.name, Description = ex.value, ColumnTyp ...