Spring AOP实现原理
AOP(Aspect Orient Programming),称之为面向切面编程。Spring AOP是使用了动态代理实现的,所谓的动态代理就是说Spring不会去修改字节码,而是在内存中临时为方法生成一个代理对象,这个代理对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是InvocationHandler接口和Proxy类。
如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,它可以在运行期动态扩展Java类与实现Java接口,通俗说CGLIB可以在运行时动态生成字节码。注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。
1、JDK动态代理
JDK动态代理要求被代理的类必须至少实现一个接口,如果目标类没有实现接口,则不能使用JDK动态代理,只能使用CGLIB动态代理。JDK动态代理会创建一个与目标类实现相同接口的代理类,然后创建该类的对象,在相应的切点做增强处理,然后调用目标对象的同名方法。
下面实现一个简单的JDK动态代理:
先定义一个接口:
public interface Person {public abstract void say();}
给定一个该接口的实现类:
public class Chinese implements Person{public void say() {System.out.println("你好!"); }}
下面是实现动态代理的核心类,该类实现了InvocationHandler接口:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class MyInvocationHandler implements InvocationHandler{//被代理的对象private Object target;public Object getProxy(Object target){this.target=target;//通过Proxy类创建代理对象,该对象的代理类实现了getInterfaces()指定的一系列接口return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);}public Object invoke(Object proxy, Method method, Object[] args) throws Exception{//织入前置增强处理System.out.println("前置处理。。。");//采用反射方式调用目标对象的方法Object result=method.invoke(target, args);//织入后置增强处理System.out.println("后置处理。。。");//方法的返回值return result;}}
下面是测试类:
public class Test {public static void main(String[] args){MyInvocationHandler myInvocationHandler=new MyInvocationHandler();Person chinese=(Person) myInvocationHandler.getProxy(new Chinese());chinese.say();}}
运行结果:
前置处理。。。
你好!
后置处理。。。
可以看到,目标类Chinese被进行了增强处理。
JDK动态代理的核心是InvocationHandler接口和Proxy类,下面讲解一下InvocationHandler接口的invoke()方法和Proxy类的newProxyInstance()方法。
InvocationHandler接口:
public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}
参数说明:
Object proxy:指被代理的对象。
Method method:要调用的方法
Object[] args:方法调用时所需要的参数
Proxy类提供了用于创建动态代理类和代理对象的静态方法,可以通过此类为一个或多个接口动态地生成实现类,它也是所有动态代理类的父类,此类提供了如下的操作方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,
InvocationHandler h) throws IllegalArgumentException
参数说明:
ClassLoader loader:生成动态代理类的类加载器
Class<?>[] interfaces:目标类(被代理类)实现的所有接口
InvocationHandler h:得到InvocationHandler接口的子类实例
2、CGLIB动态代理
CGLIB是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
下面定义一个类,该类并没有实现任何接口:
public class Chinese {public void say(){System.out.println("你好!");}}
下面是实现CGLIB动态代理的核心类,该类实现了MethodInterceptor接口:
import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;public class DynamicProxy implements MethodInterceptor{//被代理的对象private Object target;public Object getProxy(Object target){this.target=target;//创建增强器,用来动态创建代理类Enhancer enhancer=new Enhancer();//设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦截enhancer.setCallback(this);//为要生成的代理类指定父类enhancer.setSuperclass(target.getClass());//创建代理类的对象return enhancer.create();}public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {//织入增强处理System.out.println("前置处理。。。");//调用相应方法//等价于Object result=method.invoke(target, args);//等价于Object result=methodProxy.invokeSuper(object, args); Object result=methodProxy.invoke(target, args);//织入增强处理System.out.println("后置处理。。。");return result;}}
intercept()方法参数说明:
Object object:生成的代理类的实例
Method method:被代理类的方法
Object[] args:方法的参数
MethodProxy methodProxy:代理类的方法
下面是测试类:
public class Test {public static void main(String[] args) {DynamicProxy proxy=new DynamicProxy();Chinese chinese=(Chinese)proxy.getProxy(new Chinese());chinese.say();}}
运行结果如下:
前置处理。。。
你好!
后置处理。。。
可以看到Chinese类的say()方法被进行了增强处理。
Spring AOP的应用场景:
- 访问控制
- 日志记录
- 事务管理
- 性能监测
- 对象池管理
- 缓存
Spring AOP实现原理相关推荐
- Spring AOP实现原理,从代理说起
前言 为了理解Spring AOP,我们先来了解一下Java的代理模式 什么是代理? 举个例子来说明代理的作用: 假设我们想邀请一位明星,那么并不是直接联系明星,而是联系明星的经纪人,来达到同样的目的 ...
- spring注解驱动开发-6 Spring AOP实现原理
Spring AOP实现原理 前言 1.@EnableAspectJAutoProxy注解原理 2.AnnotationAwareAspectJAutoProxyCreator 分析 1.分析前工作, ...
- ppst——技术视频spring AOP 的原理讲解和简单实现
ppst 技术视频--spring AOP 的原理讲解和简单实现:请访问ppst 技术视频分享平台 , www.ppst.cc,上面有最新的技术视频,推荐大家把博客录制成视频吧,可以获取收益哦 1.s ...
- 灵魂画手图解Spring AOP实现原理!
本篇旨在让读者对Spring AOP实现原理有一个宏观上的认识,因此会丢失一些细节,具体实现参考:老实人Spring源码目录 阅读本篇文章前,希望读者对Spring Ioc以及Spring AOP的使 ...
- 探秘Spring AOP (六) Spring AOP 实现原理 1
2019独角兽企业重金招聘Python工程师标准>>> 探秘Spring AOP 一.织入的时机原理概述 1.编译期(AspectJ) 2.类加载时(AspectJ 5+) 3.运行 ...
- Spring AOP 实现原理与 CGLIB 应用--转
AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务,如事务管理.安全检查.缓存.对象池管理等.AOP 实现的关键就在于 ...
- Spring AOP 实现原理与 CGLIB 应用
WeiboGoogle+用电子邮件发送本页面 10 AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务,如事务管理.安 ...
- spring aop实现原理_Spring 异步实现原理与实战分享
最近因为全链路压测项目需要对用户自定义线程池 Bean 进行适配工作,我们知道全链路压测的核心思想是对流量压测进行标记,因此我们需要给压测的流量请求进行打标,并在链路中进行传递,那么问题来了,如果项目 ...
- Spring AOP:原理、 通知、连接点、切点、切面、表达式
0:Spring AOP 原理 简单说说 AOP 的设计: 每个 Bean 都会被 JDK 或者 Cglib 代理.取决于是否有接口. 每个 Bean 会有多个"方法拦截器".注意 ...
- 常见面试题 | Spring AOP 实现原理
实现AOP的技术,主要分为两大类: 一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执 行:二是采用静态织入的方式,引入特定的语法创建"方面",从而 ...
最新文章
- Windows客户端C/C++编程规范“建议”——表达式和运算
- 【linux】NXP MFGTools工具配置文件详解
- SAP S4HANA如何取到采购订单ITEM里的'条件'选项卡里的条件类型值?
- linux安装python虚拟环境_linux环境下安装python虚拟环境及注意事项
- Flex+J2EE获取FlexSession的方法
- 剑指offer---包含min函数的栈
- Ubuntu中安装python3
- js实战代码系列—周杰伦给你报时间+网页页签制作模板+jQuery初体验
- [转] ASP.NET中使用javascript
- 【读书笔记】 —— 公平与正义
- SSM框架面试题整理
- 2020微博热点数据简析
- PAT1003 我要通过! (20 分)(C语言)
- Arch Linux KDE Plasma + Windows 11 双系统安装指南
- 石子合并——最经典的dp问题
- json spirit_Spirit App:Web实时轻松动画
- sporadic偶发实时任务多核分区动态优先级EDF(或者DM)调度(以及可调度性分析)经典算法详解
- vue-quill-editor富文本编辑器自定义上传图片功能
- 百度云图片识别(ImageRecognition) 针对 各种图片识别的例子
- 织梦DEDE三级栏目导航实现 亲测有效
热门文章
- javascript页面刷新的几种方法
- 20多个好用的 Vue 组件库
- 【解决方法】Socket服务端退出之后端口依旧被占用
- matlab二重积分计算程序,MATLAB在二重积分计算中的应用
- git与svn的区别
- 导纳矩阵 matlab,matlab实现导纳矩阵
- 手机无法服务器获取信息,荒野行动获取服务器信息一直不动怎么办 获取服务器信息为0解决方法...
- MarkDown桌面版使用下载+安装+使用教程(包括全套的使用语法,欢迎大家查看)
- 批量图片处理:如何给多个图片都加上连续的序号?
- 毕业论文答辩PPT模板