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章类型信息的更多相关文章

  1. Java编程思想读书笔记_第二章

    java对于将一个较大作用域的变量“隐藏”的场景会有保护:编译告警.比如: int x = 5; { int x = 6; } 但是对于类中方法的局部变量和类成员变量确是可以重名的,比如 class ...

  2. Java编程思想读书笔记--第21章并发

    1.基本的线程机制 定义任务 public class LiftOff implements Runnable{ protected int countDown = 10; private stati ...

  3. JAVA编程思想读书笔记(三)--RTTI

    接上篇JAVA编程思想读书笔记(二) 第十一章 运行期类型判定 No1: 对于作为程序一部分的每个类,它们都有一个Class对象.换言之,每次写一个新类时,同时也会创建一个Class对象(更恰当的说, ...

  4. JAVA编程思想读书笔记(五)--多线程

    接上篇JAVA编程思想读书笔记(四)--对象的克隆 No1: daemon Thread(守护线程) 参考http://blog.csdn.net/pony_maggie/article/detail ...

  5. JAVA编程思想读书笔记(四)--对象的克隆

    接上篇JAVA编程思想读书笔记(三)--RTTI No1: 类的克隆 public class MyObject implements Cloneable { int i; public MyObje ...

  6. JAVA编程思想读书笔记(二)--容器

    接上篇JAVA编程思想读书笔记(一) 第八章.对象的容纳 No1: java提供了四种类型的集合类:Vector(矢量).BitSet(位集).Stack(堆栈).Hashtable(散列表) No2 ...

  7. Java编程思想读书笔记(一)【对象导论】

    2018年1月7日15:45:58 前言 作为学习Java语言的经典之作<Java编程思想>,常常被人提起.虽然这本书出版十年有余,但是内容还是很给力的.很多人说这本书不是很适合初学者,我 ...

  8. [Java编程思想-学习笔记]第3章 操作符

    3.1  更简单的打印语句 学习编程语言的通许遇到的第一个程序无非打印"Hello, world"了,然而在Java中要写成 System.out.println("He ...

  9. Java编程思想读书笔记之内部类

    现在是够懒得了,放假的时候就想把这篇笔记写出来,一直拖到现在,最近在读<Java编程思想>,我想会做不止这一篇笔记,因为之前面试的时候总会问道一些内部类的问题,那这本书的笔记就从内部类开始 ...

随机推荐

  1. CMD-NET命令详解(转载)

    本文转自http://www.cnblogs.com/chenjq0717/archive/2010/05/09/1730934.html net命令大全,net命令用法,net网络命令,net命令使 ...

  2. ECSHOP在线手册布局参考图--文章列表页 article_cat.dwt

        A.购物车 1,设置方法 程序自动读取购物车的商品数量 2,代码相关 cart.lbi 中 {insert_scripts files='transport.js'} <div clas ...

  3. SQLite使用教程9 Select 语句

    http://www.runoob.com/sqlite/sqlite-select.html SQLite Select 语句 SQLite 的 SELECT 语句用于从 SQLite 数据库表中获 ...

  4. eclipse 护眼色

    eclipse windows 窗口背景颜色 保护视力 博客分类: 工具使用 EclipseWindows  eclipse  窗口背景颜色 windows 窗口背景颜色

  5. C#-datagridview隐藏行头

    在进行datagridview的设置的过程中,常常会遇到需要设定datagridview1的行头显示,这就需要用到datagridview的属性: RowHeadersVisible属性设置为fals ...

  6. 飘逸的python - 理解打开文件的模式

    当我们用open()函数去打开文件的时候,有好几种打开的模式.   'r'->只读 'w'->只写,文件已存在则清空,不存在则创建. 'a'->追加,写到文件末尾 'b'->二 ...

  7. [Open Projects Series] ViewPagerTransforms

    https://github.com/jfeinstein10/JazzyViewPager https://github.com/ToxicBakery/ViewPagerTransforms

  8. [MODx] Build a CMP (Custom manager page) using MIGX in MODX 2.3 -- 1

    BIG FUCK for MODx MODx document is not that good  ...  at least in my opint of view. I spend hours t ...

  9. ATF批量导出工具

    ATF批量导出工具 08 / 31, 2013 批量导出Atf的工具,使用是adobe atf 编码核心 先说一下关于atf的bug 当atf导出时候启用了mips选项会导致:如果纹理问长方形时上传会 ...

  10. IaaS层市场科普

    简介 这是本博客系列云计算相关文章中的第二篇,所有文章请参考: 博客所有文章 本文主要介绍了一下当前IaaS层市场上的几个主要角色,这几个角色的历史发展以及现状. 开源市场 CloudStack 一句 ...