一、代理模式

如图:由于某些原因我们希望对该实现类进行访问控制、功能增强等,那么加入一层代理层,用代理层来调用实现类是一个很好的方式来解决这个问题,我们可以在调用实现类功能前后进行校验或者加入一些功能来达到控制、增强等效果。

你可以将代理模式简单理解为:不直接面向实现类,而是面向代理类,通过代理类调用实现类这一中间过程达到控制和增强的目的。

二、JDK动态代理

JDK提供了动态的代理实例创建的方法,你会用到:

在java.lang.reflect包下:

1)InvocationHandler代理处理程序接口

2)Proxy代理创建类

你需要使用步骤如下:

1)创建接口

2)创建接口实现类

3)实现代理处理程序InvocationHandler

4)Proxy创建代理

1、创建接口

/**
* 接口
*/
interface Person {
void say();
}

2、创建接口实现类

/**
* 实现类
*/
class Lay implements Person { @Override
public void say() {
System.out.println("the weather is very nice");
} }

3、创建代理处理程序

/**
* 代理处理实现
*/
class InvokeHandlerImpl implements InvocationHandler { private Object subject; public InvokeHandlerImpl(Object subject) {
this.subject = subject;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置处理");
Object result = method.invoke(subject, args);
System.out.println("后置处理");
return result;
} }

注意:

1)InvokeHanlderImpl(Object subject); 构造方法传入了需要被代理的实现类实例对象;

2)proxy是代理实例对象;

3)method是被调用的方法;

4)args是method的参数;

4、创建代理

public class ProxyTest {

    public static void main(String[] args) {
Person lay = new Lay();
Person person = (Person) Proxy.newProxyInstance(lay.getClass().getClassLoader(), lay.getClass().getInterfaces(), new InvokeHandlerImpl(lay));
person.say();
} }

注意:

1)Proxy.newProxyInstance(...)方法创建了lay实例对象的代理;

2)第一个参数是类加载器;

3)第二个参数是相应声明的接口;

4)第三个参数是之前的代理处理程序;

控制台打印如下:

前置处理
the weather is very nice
后置处理

上面这个示例展示了JDK动态代理如何使用的,那么我们可以回想一下Spring框架中AOP、拦截器、事务等是不是也是一样的处理逻辑呢?所以Spring其实利用代理来做了很多事情。

三、为什么JDK动态代理基于接口

在上面的示例中,我们可能会疑惑,为什么一定要写一个Person接口,为什么在创建代理的时候需要传入接口呢?

打开newProxyInstance(...)源码你会看到(省略了代码):

...
Class<?> cl = getProxyClass0(loader, intfs);
...
final Constructor<?> cons = cl.getConstructor(constructorParams);
...
return cons.newInstance(new Object[]{h});

getProxyClass0方法通过加载器和接口获取了一个新类,这个类是接口的的实现类,而后通过构造方法创建了一个实例对象,这个实例对象就是代理对象。

我们可以这么理解代理对象和实现类之间的关系:

所以,代理对象和实现类的对象是两个对象,因此你可以知道如果你把代理对象强转成实现类是会报错的,因而你需要向上转型为接口。

Java API 之 动态代理的更多相关文章

  1. 使用Java中的动态代理实现数据库连接池

    2002 年 12 月 05 日 作者通过使用JAVA中的动态代理实现数据库连接池,使使用者可以以普通的jdbc连接的使用习惯来使用连接池. 数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的 ...

  2. Java 反射 设计模式 动态代理机制详解 [ 转载 ]

    Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...

  3. 杨晓峰-Java核心技术-6 动态代理 反射 MD

    目录 第6讲 | 动态代理是基于什么原理? 典型回答 考点分析 知识扩展 反射机制及其演进 动态代理 精选留言 Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAnd ...

  4. 深入分析Java反射(四)-动态代理

    动态代理的简介 Java动态代理机制的出现,使得Java开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分 ...

  5. java 笔记(3) —— 动态代理,静态代理,cglib代理

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

  6. java中的动态代理机制

    java中的动态代理机制 在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Class),这一个类和接口是实现 ...

  7. Java反射和动态代理

    Java反射 反射机制 RTTI 编译器在编译时打开和检查*.class文件 反射机制 运行时打开和检查*.class文件 Java反射常见的方法 java反射的应用 setAccessible(bo ...

  8. Java学习笔记--动态代理

    动态代理 1.JDK动态代理 JDK1.3之后,Java提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy ...

  9. 十分钟理解Java中的动态代理

    十分钟理解 Java 中的动态代理   一.概述 1. 什么是代理 我们大家都知道微商代理,简单地说就是代替厂家卖商品,厂家“委托”代理为其销售商品.关于微商代理,首先我们从他们那里买东西时通常不知道 ...

随机推荐

  1. View-Controller-Containment

    willMove(toParentViewController:) 调用时机 调用addChildViewController(_:)以钱会被自动调用 调用removeFromParentViewCo ...

  2. python使用python-docx导出word

    #!/usr/bin/env python # -*- coding: utf-8 -*- ''' ''' from docx import Document from docx.shared imp ...

  3. ipython 导入模块 非法ascii字符问题

    SyntaxError: Non-ASCII character '\xe2‘ ipython  使用了 python2    加入 #coding=utf-8 ipython3 使用 python3

  4. 读取Excel表格日期类型数据的时候

    用POI读取Excel数据:(版本号:POI3.7) 1.读取Excel 2.Excel数据处理: Excel存储日期.时间均以数值类型进行存储,读取时POI先判断是是否是数值类型,再进行判断转化 1 ...

  5. BZOJ - 3166 可持久化Trie 维护次大区间

    题意:给出\(a[1...n]\),找出一个连续区间\(a[l...r],r>l\),令该区间的次大值为\(a_k\),使得\(a_k⊕a_i,l≤i≤r\)最大,输出全局最优解 (这题意有点别 ...

  6. 验证客户端的链接合法性和socketserver模块实现并发

    本节内容: 1.验证客户端的链接合法性 2.socketserver模块实现并发 一.验证客户端的链接合法性 首先,我们来探讨一下,什么叫验证合法性, 举个例子:有一天,我开了一个socket服务端, ...

  7. JobScheduler布置后台任务以及实现进程保活?

    1.简介 在Android 5.0 提供了一套新的 JobScheduler API,它允许您定义要在以后的某个时间或在指定的条件下(例如,当设备在充电时)异步运行的作业来优化电池寿命. https: ...

  8. centos 7 下安装nginx-1.15.7

    安装所需环境 Nginx 是 C语言 开发,建议在 Linux 上运行,当然,也可以安装 Windows 版本,本篇则使用 CentOS 7 作为安装环境. 一. gcc 安装安装 nginx 需要先 ...

  9. activeMQ入门+spring boot整合activeMQ

    最近想要学习MOM(消息中间件:Message Oriented Middleware),就从比较基础的activeMQ学起,rabbitMQ.zeroMQ.rocketMQ.Kafka等后续再去学习 ...

  10. idea常用快捷汇总

    目录 1.查询 2. 自动提示 3. 代码生成 4. 摆脱鼠标 5.源码阅读 1.查询 Shift+ Ctrl + F 全文搜索 Shift + Shift 文件名搜索 Ctrl + F 在当前文件进 ...