日常工作中经常会接触到代理模式,但一直没有对其进行深究。代理模式一直就像一团迷雾一样存在我心里,什么是代理模式?为什么要使用代理?代理模式有哪些实现?它的底层机制是怎样的?这些问题促使着我迫切想要揭开代理模式的神秘面纱。

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]----代理模式实现方式的概要介绍的更多相关文章

  1. JDK动态代理[2]----JDK动态代理的底层实现之Proxy源码分析

    在上一篇里为大家简单介绍了什么是代理模式?为什么要使用代理模式?并用例子演示了一下静态代理和动态代理的实现,分析了静态代理和动态代理各自的优缺点.在这一篇中笔者打算深入源码为大家剖析JDK动态代理实现 ...

  2. JDK动态代理[4]----ProxyGenerator生成代理类的字节码文件解析

    通过前面几篇的分析,我们知道代理类是通过Proxy类的ProxyClassFactory工厂生成的,这个工厂类会去调用ProxyGenerator类的generateProxyClass()方法来生成 ...

  3. 动态代理的两种实现方式(JDK/Cglib)

    =========================================== 原文链接: 动态代理的两种实现方式(JDK/Cglib) 转载请注明出处! ================== ...

  4. 代理模式(静态代理、JDK动态代理原理分析、CGLIB动态代理)

    代理模式 代理模式是设计模式之一,为一个对象提供一个替身或者占位符以控制对这个对象的访问,它给目标对象提供一个代理对象,由代理对象控制对目标对象的访问. 那么为什么要使用代理模式呢? 1.隔离,客户端 ...

  5. Spring的两种代理方式:JDK动态代理和CGLIB动态代理

    代理模式 代理模式的英文叫做Proxy或Surrogate,中文都可译为”代理“,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对 ...

  6. 代理模式 静态代理、JDK动态代理、Cglib动态代理

    1 代理模式 使用代理模式时必须让代理类和被代理类实现相同的接口: 客户端通过代理类对象来调用被代理对象方法时,代理类对象会将所有方法的调用分派到被代理对象上进行反射执行: 在分派的过程中还可以添加前 ...

  7. 从静态代理,jdk动态代理到cglib动态代理-一文搞懂代理模式

    从代理模式到动态代理 代理模式是一种理论上非常简单,但是各种地方的实现往往却非常复杂.本文将从代理模式的基本概念出发,探讨代理模式在java领域的应用与实现.读完本文你将get到以下几点: 为什么需要 ...

  8. 代理模式之静态代理,JDK动态代理和cglib动态代理

    代理模式,顾名思义,就是通过代理去完成某些功能.比如,你需要购买火车票,不想跑那么远到火车站售票窗口买,可以去附近的火车票代售点买,或者到携程等第三方网站买.这个时候,我们就把火车站叫做目标对象或者委 ...

  9. 代理模式详解:静态代理、JDK动态代理与Cglib动态代理

    代理模式简介分类 概念 ​ 代理,是为了在不修改目标对象的基础上,增强目标方法的业务逻辑. ​ 客户类需要执行的是目标对象的目标方法,但是真正执行的是代理对象的代理方法,客户类对目标对象的访问是通过代 ...

随机推荐

  1. ERP服务器简单维护

    前言: 此页内容对于网管高手来说是小儿科,但是以我们对大多数企业的了解,依然有好多企业将服务器的日常维护给忽视了. 所以在此,给大家做一个宣传.让大家提高服务器维护的意识 以提高服务器运行的稳定性.安 ...

  2. OC面向对象的三大特性

    一.面向对象的三大特性:封装(成员变量).继承和多态 1. set方法和get方法 1. set方法和get方法的使用场合 @public的成员可以被随意赋值,应该使用set方法和get方法来管理成员 ...

  3. 逆波兰表达式POJ——2694

    问题描述: 逆波兰表达式是一种吧运算符前置的算术表达式,例如普通的表达式2+3的逆波兰表示为+23.逆波兰表达式的优点是运算符之间不必有优先级的关系,也不必有括号改变运算次序,例如(2+3)*4的逆波 ...

  4. ASP.NET Core 一步步搭建个人网站(2)_一键部署和用户注册登录

    俗话说,磨刀不费砍柴工.为了更方便的进行项目管理,我们先将个人网站项目配置一下,满足以下2个目标: VS2017中支持Git存储库,绑定Github项目,实现本地VS程序与线上Github一键代码提交 ...

  5. Spring Data 整合 ElasticSearch搜索服务器

    一.基于 maven 导入坐标(pom.xml文件) <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi ...

  6. python学习之路day1

    学习总结: 变量,字符的由来,python2和python3的区别,控制语句:if,for,while,break,continue用法 学习示例: if用法1:判断年龄 # -*- coding: ...

  7. Web 动画帧率(FPS)计算

    我们知道,动画其实是由一帧一帧的图像构成的.有 Web 动画那么就会存在该动画在播放运行时的帧率.而帧率在不同设备不同情况下又是不一样的. 有的时候,一些复杂或者重要动画,我们需要实时监控它们的帧率, ...

  8. Python2/3中的urllib库

    urllib库对照速查表 Python2.X Python3.X urllib urllib.request, urllib.error, urllib.parse urllib2 urllib.re ...

  9. 好好写代码吧,没事别瞎B去创业!

    知乎上看到这个问题 正好最近想写篇关于此的文章,于是就回答了一波. 也贴到这里来,回答如下 : 本问题简直为我量身定制,做为一个正在创业中的苦逼少年,说说我是如何从鼓吹怂恿身边人创业转换成反对创业的. ...

  10. 【JDK1.8】JDK1.8集合源码阅读——ArrayList

    一.前言 在前面几篇,我们已经学习了常见了Map,下面开始阅读实现Collection接口的常见的实现类.在有了之前源码的铺垫之后,我们后面的阅读之路将会变得简单很多,因为很多Collection的结 ...