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. Winform- 界面开发之布局控件"WeifenLuo.WinFormsUI.Docking"的使用

    布局控件"WeifenLuo.WinFormsUI.Docking"是一个非常棒的开源控件,用过的人都深有体会,该控件之强大.美观.不亚于商业控件.而且控件使用也是比较简单的. 实 ...

  2. Spring Framework 5.0.0.M3中文文档 翻译记录 Part I. Spring框架概览1-2.2

    Part I. Spring框架概览 The Spring Framework is a lightweight solution and a potential one-stop-shop for ...

  3. 利用Chrome模拟访问移动端网页

    很多网站都通过User-Agent来判断浏览器类型,如果是3G手机,显示手机页面内容,如果是普通浏览器,显示普通网页内容. 谷歌Chrome浏览器,可以很方便地用来当3G手机模拟器.在Windows的 ...

  4. -join 和 -split 用法

    具体可参考 PowerShell_ISE的帮助文件: -Join(一元联接运算符): 一元联接运算符 (-join <string[]>) 的优先级高于逗号.因此,如果向一元联接运算符提交 ...

  5. [Practical Git] Format commit history with git log arguments

    When running the git log command, we can pass in options as arguments toformat the data shown for ea ...

  6. 会话跟踪session cookie

    会话跟踪 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在 ...

  7. 管道技巧-while read line

    http://blog.csdn.net/hunanchenxingyu/article/details/9998089

  8. careercup-中等难度 17.9

    17.9 设计一个方法,找出任意指定单词在一本书中的出现频率. 解法: 1 单次查询 遍历这本书的每个单词,计算给定单词出现的次数.时间复杂度O(n),我们无法继续优化它,因为书中的每个单次都需要访问 ...

  9. Hibernate: Truly Understanding the Second-Level and Query Caches--reference

    I've written multiple articles here at Javalobby on the Hibernate O/R mapping tool, and they are usu ...

  10. sqlite数据下载链接地址

    链接: http://pan.baidu.com/s/1pJN1abT 密码: yjg5