一、代理模式

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

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

二、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. Linux系统管理 常用命令

    基础常用命令 某个命令 --h,对这个命令进行解释 某个命令 --help,解释这个命令(更详细) man某个命令,文档式解释这个命令(更更详细)(执行该命令后,还可以按/+关键字进行查询结果的搜索) ...

  2. “全栈2019”Java第五十八章:多态中方法返回类型可以是子类类型

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  3. fread和fwrite用法小结

    fwrite和fread是以记录为单位的I/O函数,fread和fwrite函数一般用于二进制文件的输入输出. #include <stdio.h>size_t fread(void *p ...

  4. centos6.5 命令行配置无线上网

    1.驱动下载地址: RTL8188无线网卡驱动下载 链接:https://pan.baidu.com/s/1ms-EbQCDxa76jPhYUPmr9Q 密码:r2vu 2.安装步骤: [root@c ...

  5. awk常用用法

    一. 基本使用方法: awk '{pattern + action}' filenames #其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列 ...

  6. maven初步了解

    目标:创建一个父maven项目,有两个子项目分别为serverCenter,dbConnector. 建议:全程不要导入Jar包,全部使用maven依赖的方式导入包. 1.创建maven项目 这个创建 ...

  7. 跟刘欣学习造spring

    1: 读取配置文件并获取对象实例

  8. css 移动端图片等比显示处理

    第一次写博文,心情有点小小的激动~~~~~ 刚开始做移动端项目的时候遇到了一些优化的问题,比如,打开网页在2g或者3g的情况下加载网页,刚开始渲染的时候,遇到图片文件未请求,图片的高度会为0,当然,如 ...

  9. Linux 包管理器

    RPM: rpm(Red-Hat Package Manager) 为 Redhat 提出的包管理器, 用于在 Redhat 及其衍生版本中安装 rpm 格式的软件包 rpm 的优点: 1.简化了源码 ...

  10. 2016级算法第三次上机-D.双十一的抉择

    915 双十一的抉择 思路 中等题.简化题目:一共n个数,分成两组,使得两组的差最接近0,就是说要使两组数都尽可能的接近sum/2. 思路还是很混乱的,不知道如何下手,暴力也挺难的,还不能保证对.想一 ...