JDK动态代理[1]----代理模式实现方式的概要介绍
日常工作中经常会接触到代理模式,但一直没有对其进行深究。代理模式一直就像一团迷雾一样存在我心里,什么是代理模式?为什么要使用代理?代理模式有哪些实现?它的底层机制是怎样的?这些问题促使着我迫切想要揭开代理模式的神秘面纱。
1. 什么是代理模式?
日常生活中我们经常会碰到代理模式,例如我们找房产中介帮我们介绍房子,找婚姻中介帮我们介绍对象,找保洁帮我们打理房间,找律师帮我们进行诉讼等。我们在无形中运用到了代理模式,却不知道它的存在。
2. 为什么要使用代理?
运用代理可以使我们的生活更加便利,有了代理,我们不需要自己去找房子,不需要自己去找对象,不需要自己去打理房间,不需要自己去诉讼。当然,你也可以选择一切都自己来干,但是存在前提条件,一是你是否都具备这样的资源和能力来做这些事情,二是你是否愿意花费这么多精力和时间来做这些事情。总之,代理模式使我们各专其事,我们可以将时间浪费在美好的事情上,而不用天天被一些琐事所羁绊。
3. 代理模式有哪些实现?
Java中的代理有静态代理和动态代理,下面我会分别用一个简单的例子来介绍一下静态代理和动态代理代码实现。
3.1 静态代理
代理接口:UserDao.java
public interface UserDao {
void save();
}
目标对象:UserDaoImpl.java
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("正在保存用户...");
}
}
代理对象:TransactionHandler.java
public class TransactionHandler implements UserDao {
//目标代理对象
private UserDaoImpl target;
//构造代理对象时传入目标对象
public TransactionHandler(UserDaoImpl target) {
this.target = target;
}
@Override
public void save() {
//调用目标方法前的处理
System.out.println("开启事务控制...");
//调用目标对象的方法
target.save();
//调用目标方法后的处理
System.out.println("关闭事务控制...");
}
}
测试类:Main.java
public class Main {
public static void main(String[] args) {
//新建目标对象
UserDaoImpl target = new UserDaoImpl();
//创建代理对象, 并使用接口对其进行引用
UserDao userDao = new TransactionHandler(target);
//针对接口进行调用
userDao.save();
}
}
测试结果:

总结:
总的来说静态代理实现简单也容易理解,但是静态代理不能使一个代理类反复作用于多个目标对象,代理对象直接持有目标对象的引用,这导致代理对象和目标对象类型紧密耦合了在一起。如果UserDao接口下还有另一个实现类也需要进行事务控制,那么就要重新写一个代理类,这样就会产生许多重复的模版代码,不能达到代码复用的目的。而动态代理就可以很好的解决这样的问题。
3.2 动态代理
代理接口:UserDao.java
public interface UserDao {
void save();
}
目标对象:UserDaoImpl.java
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("保存用户信息...");
}
}
代理对象:TransactionHandler.java
public class TransactionHandler implements InvocationHandler {
//需要代理的目标对象
//这里设计为可以为任意对象添加事务控制, 所以将目标对象声明为Object
private Object target;
//构造TransactionHandler时传入目标对象
public TransactionHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//调用目标方法前的处理
System.out.println("开启事务控制...");
//调用目标对象的方法
Object result = method.invoke(target, args);
//调用目标方法后的处理
System.out.println("关闭事务控制...");
//放回方法调用结果
return result;
}
}
测试类:Main.java
public class Main {
public static void main(String[] args) {
//新建目标对象
Object target = new UserDaoImpl();
//创建事务处理器
TransactionHandler handler = new TransactionHandler(target);
//生成代理类并使用接口对其进行引用
UserDao userDao = (UserDao)Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
handler);
//针对接口进行方法调用
userDao.save();
}
}
测试结果:

总结:
之前我们发现了静态代理会产生许多重复代码,不能很好的进行代码复用,而动态代理能够很好的解决这个问题,代理类TransactionHandler实现了InvocationHandler接口,并且它持有的目标对象类型是Object,因此事务控制代理类TransactionHandler能够代理任意的对象,为任意的对象添加事务控制的逻辑。因此动态代理才真正的将代码中横向切面的逻辑剥离了出来,起到代码复用的目的。但是动态代理也有缺点,一是它的实现比静态代理更加复杂也不好理解;二是它存在一定的限制,例如它要求需要代理的对象必须实现了某个接口;三是它不够灵活,动态代理会为接口中的声明的所有方法添加上相同的代理逻辑。当然,这只是JDK动态代理所存在的一些缺陷,动态代理还有另外的实现如使用CGLIB库,在本文不做介绍,读者可以自行去了解。
全文总结:
本文从概念上为大家介绍了什么是代理模式,为什么要使用代理以及代理模式有哪些实现,并使用简单的例子为大家介绍静态代理和JDK动态代理的实现,分析了静态代理和动态代理各自的优缺点,使大家对代理模式有了一些大致的了解。不过到这里相信读者对于JDK动态代理还是会感到困惑,想要进一步了解代理类是怎样产生的。后续章节笔者会深入源码为大家呈现整个代理类的产生过程。
JDK动态代理[1]----代理模式实现方式的概要介绍的更多相关文章
- JDK动态代理[2]----JDK动态代理的底层实现之Proxy源码分析
在上一篇里为大家简单介绍了什么是代理模式?为什么要使用代理模式?并用例子演示了一下静态代理和动态代理的实现,分析了静态代理和动态代理各自的优缺点.在这一篇中笔者打算深入源码为大家剖析JDK动态代理实现 ...
- JDK动态代理[4]----ProxyGenerator生成代理类的字节码文件解析
通过前面几篇的分析,我们知道代理类是通过Proxy类的ProxyClassFactory工厂生成的,这个工厂类会去调用ProxyGenerator类的generateProxyClass()方法来生成 ...
- 动态代理的两种实现方式(JDK/Cglib)
=========================================== 原文链接: 动态代理的两种实现方式(JDK/Cglib) 转载请注明出处! ================== ...
- 代理模式(静态代理、JDK动态代理原理分析、CGLIB动态代理)
代理模式 代理模式是设计模式之一,为一个对象提供一个替身或者占位符以控制对这个对象的访问,它给目标对象提供一个代理对象,由代理对象控制对目标对象的访问. 那么为什么要使用代理模式呢? 1.隔离,客户端 ...
- Spring的两种代理方式:JDK动态代理和CGLIB动态代理
代理模式 代理模式的英文叫做Proxy或Surrogate,中文都可译为”代理“,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对 ...
- 代理模式 静态代理、JDK动态代理、Cglib动态代理
1 代理模式 使用代理模式时必须让代理类和被代理类实现相同的接口: 客户端通过代理类对象来调用被代理对象方法时,代理类对象会将所有方法的调用分派到被代理对象上进行反射执行: 在分派的过程中还可以添加前 ...
- 从静态代理,jdk动态代理到cglib动态代理-一文搞懂代理模式
从代理模式到动态代理 代理模式是一种理论上非常简单,但是各种地方的实现往往却非常复杂.本文将从代理模式的基本概念出发,探讨代理模式在java领域的应用与实现.读完本文你将get到以下几点: 为什么需要 ...
- 代理模式之静态代理,JDK动态代理和cglib动态代理
代理模式,顾名思义,就是通过代理去完成某些功能.比如,你需要购买火车票,不想跑那么远到火车站售票窗口买,可以去附近的火车票代售点买,或者到携程等第三方网站买.这个时候,我们就把火车站叫做目标对象或者委 ...
- 代理模式详解:静态代理、JDK动态代理与Cglib动态代理
代理模式简介分类 概念 代理,是为了在不修改目标对象的基础上,增强目标方法的业务逻辑. 客户类需要执行的是目标对象的目标方法,但是真正执行的是代理对象的代理方法,客户类对目标对象的访问是通过代 ...
随机推荐
- 为什么ERP行业发展缓慢规模难扩大?
题记:这个行业只会越来越好,但是能沉淀下来做事儿的企业越来越少,因为收益真的很漫长:能够真正进入这个行业难,出去也难... 经常在知乎上看到类似的问题:既然所有ERP系统都很烂,那有没有创业公司的空间 ...
- Java8 HashMap源码分析
java.util.HashMap是最常用的java容器类之一, 它是一个线程不安全的容器. 本文对JDK1.8.0中的HashMap实现源码进行分析. HashMap使用位运算巧妙的进行散列并使用链 ...
- strlen 与 sizeof
#include<stdio.h>#include<string.h>#include<string>#include<iostream>using n ...
- Rsync同步、Rsync+Lsync实时同步
Rsync同步.Rsync+Lsync实时同步 原创博文http://www.cnblogs.com/elvi/p/7658049.html #!/bin/sh #Myde by Elven @ #c ...
- JavaScript OOP(三):prototype原型对象(即构造函数的prototype属性)
通过构造函数生成的实例化对象,无法共享属性或方法(即每个实例化对象上都有构造函数中的属性和方法):造成了一定的资源浪费 function Obj(name,age){ this.name=name; ...
- 乌龟棋dp
传送门题目:https://www.luogu.org/problem/show?pid=1541 其实这道题想到了就很简单,但很难想到用思维的dp,这非常少见. 看到每张牌不超过40张,这数据范围就 ...
- Python连接MySQL数据库中各种坑
第一个坑 要想连接数据库,我们必须拥有MySQL-python这个模块,首先,我在安装这个模块的时候就到了第一个大坑. 常规安装方法:进入cmd 使用 pip install MySQL-python ...
- Swift 线程安全数组
欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 作者:BigNerdCoding 有并发的地方就存在线程安全问题,尤其是对于 Swift 这种还没有内置并发支持的语言来说线程安全问题更为突出 ...
- 代码管理 ,git 命令整理
//先要理解这四个概念,这是一个提交代码的流动轨迹:1.工作区(编辑器)-经过add到2- 2.暂存区 (缓存)- 经过commit3-3.本地仓库 (本地项目)-经过 push4-4.远程仓库 (线 ...
- vue——props的两种常用方法
vue--props的两种常用方法 1.实现父-->子的通信 举例如下: 父组件 parent.vue <children :channel="object1"> ...