Spring JDK动态代理详解
文章目录
- 代理模式
- 动态代理:
- JDK动态代理
代理模式
当访问对象不适合或者不能直接引用目标对象时,需要给访问对象提供一个代理以控制对该对象的访问,代理对象作为访问对象和目标对象之间的中介。
代理模式的主要优点有:
- 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
- 代理对象可以扩展目标对象的功能;
- 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度;
其主要缺点是:
- 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
- 增加了系统的复杂度;
代理模式分为静态代理和动态代理,这里我们只对动态代理进行论述
动态代理:
- 动态代理的代理类是动态生成的,不是我们直接写好的
- 动态代理分为两大类:基于接口的动态代理和基于类的动态代理
- 基于接口:JDK动态代理
- 基于类:CGLIB
- Java字节码实现:Javasist
动态代理的好处:
- 可以使真实角色操作更加纯粹,不用去关注一些公众的事务
- 公共事务交给代理角色,实现了业务的分工
- 公共业务扩展时,方便集中管理
- 一个动态代理类代理的是一个接口,一般就是对应一类的业务
- 一个动态代理类可以代理多个类,只要是实现了同一个接口即可
JDK动态代理
Spring JDK 动态代理需要实现 InvocationHandler 接口,重写 invoke 方法,客户端使用 Java.lang.reflect.Proxy 类产生动态代理类的对象。
下面使用IDEA演示JDK动态代理过程
示例为客户通过中介向房东租房子演示:
如图所示创建客户类(Client)、房东(Host)、业务增强(MyAspect)、代理类(ProxyInvocationHandler)、接口(Rent).
接口(Rent)代码如下:
//租房子的接口
public interface Rent {public void rent();
}
房东(Host)代码如下:
//房东代码实现接口,实现租出房子
public class Host implements Rent {public void rent(){System.out.println("租出房子");}
}
业务增强(MyAspect)代码如下:
//在代理中,代理类不仅可以实现必须要实现的业务,同时还可以扩展目标对象的功能
//MyAspect 类在切面中定义了两个增强的方法,分别为 myBefore 和 myAfter。
public class MyAspect {public void myBefore() {System.out.println("方法执行之前");}public void myAfter() {System.out.println("方法执行之后");}
}
代理类(ProxyInvocationHandler)代码如下:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;//实现InvocationHandler接口生成代理类
public class ProxyInvocationHandler implements InvocationHandler {MyAspect myAspect = new MyAspect();//被代理的接口private Rent rent;public void setRent(Rent rent) {this.rent = rent;}//定义获取代理对象方法public Object getProxy(){// JDK动态代理只能代理实现了接口的类return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this);}//处理代理实例,并返回结果@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//动态代理的实质,就是反射机制的实现myAspect.myBefore();Object result = method.invoke(rent,args);myAspect.myAfter();return result;}
}
客户代码如下:
public class Client {public static void main(String[] args) {//真实角色Rent rent= new Host();//代理角色ProxyInvocationHandler pih = new ProxyInvocationHandler();//通过调用程序处理角色来处理我们要调用的接口对象pih.setRent(rent);//获取代理对象Rent proxy = (Rent) pih.getProxy();//由代理对象执行方法proxy.rent();}
}
运行结果:
小Tip:编写代理类时,只需实现InvocationHandler接口中的方法
- 获取代理对象getProxy()方法:JDK动态代理只能代理实现了接口的类,只需修改相应的接口即可
- 处理代理实例invoke()方法:除了实现接口中的功能外,还可以扩展目标对象的功能。
这样客户通过代理对象来实现接口中的方法,而不是直接通过房东实现,降低了系统的耦合度,同时扩展了目标对象的功能
Spring JDK动态代理详解相关推荐
- JAVA动态代理详解
JAVA动态代理详解 问题 1:什么是静态代理,动态代理? 2:动态代理的好处? 什么是静态代理 以生活中例子来看,我作为某某品牌面膜的北京区代理,我替厂家卖面膜,我属于代理,厂家属于委托方. 联系到 ...
- spring中aop默认使用jdk动态代理,springboot2以后默认使用cglib来实现动态代理详解
Spring5 AOP 默认使用 Cglib 了?我第一次听到这个说法是在一个微信群里: 真的假的?查阅文档 刚看到这个说法的时候,我是保持怀疑态度的. 大家都知道 Spring5 之前的版本 AOP ...
- 静态代理,JDK动态代理,Cglib动态代理详解
目录 一.代理模式 二.静态代理 三.动态代理 3.1 JDK动态代理 3.2 Cglib动态代理 四.两种动态代理区别 一.代理模式 代理模式(Proxy Pattern)是程序设计中的一种设计模式 ...
- Spring之AOP动态代理详解
动态代理 动态代理和静态代理角色一样 动态代理类是动态生成的,不是我们直接写好的. 动态代理分为两大类:基于接口的动态代理:JDK动态代理[我们在这里使用]基于类的动态代理:cglibjava字节码: ...
- Java 动态代理详解 ( 附示例源码,建议收藏)
动态代理在Java中有着广泛的应用,比如Spring AOP.Hibernate数据查询.测试框架的后端mock.RPC远程调用.Java注解对象获取.日志.用户鉴权.全局性异常处理.性能监控,甚至事 ...
- java动态代理_Java代理模式及动态代理详解
Java的动态代理在实践中有着广泛的使用场景,比如最场景的Spring AOP.Java注解的获取.日志.用户鉴权等.本篇文章带大家了解一下代理模式.静态代理以及基于JDK原生动态代理. 代理模式 无 ...
- 为什么要用动态代理?静态代理与动态代理详解
代理模式: 代理模式在Java中特别常见,如spring AOP功能就是用代理来实现的.代理模式作用是:在不修改被代理对象功能的基础上,通过对代理类进行扩展,进行一些功能上的附加与增强. 一般使用代理 ...
- Spring JDK动态代理
JDK 动态代理是通过 JDK 中的 java.lang.reflect.Proxy 类实现的.下面通过具体的案例演示 JDK 动态代理的使用. 1. 创建项目 在 MyEclipse 中创建一个名称 ...
- Java代理模式及动态代理详解
本文转自:程序新视界公众号 Java的动态代理在实践中有着广泛的使用场景,比如最场景的Spring AOP.Java注解的获取.日志.用户鉴权等.本篇文章带大家了解一下代理模式.静态代理以及基于JDK ...
- java类加载机制、反射、动态代理详解
类的加载.连接和初始化(系统可能在第一次使用某个类时加载该类, 也可能采用预加载机制来加载某个类)动态代理实现 1.JVM和类 当调用 java 命令运行某个 Java 程序时, 该命令将会启动一个 ...
最新文章
- python字符串endswith,Python字符串| 具有示例的endswith()方法
- Arduino可穿戴教程之第一个程序——连接硬件选择板子(二)
- souce insight中文出现乱码
- CentOS查看进程的线程数方法
- Python -bs4反爬虫解决方法
- 云炬随笔20161117
- MT7628/MT7688 修改串口2作为调试串口 所踩的坑
- 安装electron报错
- python通过api获取数据_在一次点击PythonRequests中从API获取所有数据
- python平均分由高到低顺序排列输出选手编号和最后得分_python 字典的使用案例二:求平均分,并按平均分由高到低输出选手编号和最后得分...
- 前端学习(1233):组件化开发思想
- php 改变图片的宽高,php缩放图片(根据宽高的等比例缩放)示例
- 在IA32如何将程序计数器的值放入到整数寄存器中?
- 伺服驱动器cn1引脚定义_伺服驱动器CN1引脚定义,和面板操作设置,跪求高手指点。说明书弄丢了.脉冲,使能,方向,接第几引脚...
- 黑客的入侵方式你知道几种?
- wps表格怎么用计算机,怎么样在wps表格中添加计算器
- 复合函数求导经典例题_导数--复合函数的导数练习题
- 计算机组成原理:时钟周期、机器周期和指令周期
- HTML5游戏实战 3 60行代码实现水平跑酷游戏
- 傅立叶变换、Gabor变换与小波变换