写点什么

一文带你搞懂从动态代理实现到 Spring AOP

发布于: 2021 年 01 月 22 日

摘要:本文主要讲了 Spring Aop 动态代理实现的两种方式。


1. Spring AOP


Spring 是一个轻型容器,Spring 整个系列的最最核心的概念当属 IoC、AOP。可见 AOP 是 Spring 框架中的核心之一,在应用中具有非常重要的作用,也是 Spring 其他组件的基础。AOP(Aspect Oriented Programming),即面向切面编程,可以说是 OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP 引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过 OOP 允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。


关于 AOP 的基础知识,并不是本文的重点,我们主要来看下 AOP 的核心功能的底层实现机制:动态代理的实现原理。AOP 的拦截功能是由 java 中的动态代理来实现的。在目标类的基础上增加切面逻辑,生成增强的目标类(该切面逻辑或者在目标类函数执行之前,或者目标类函数执行之后,或者在目标类函数抛出异常时候执行。不同的切入时机对应不同的 Interceptor 的种类,如 BeforeAdviseInterceptor,AfterAdviseInterceptor 以及 ThrowsAdviseInterceptor 等)。


那么动态代理是如何实现将切面逻辑(advise)织入到目标类方法中去的呢?下面我们就来详细介绍并实现 AOP 中用到的两种动态代理。


AOP 的源码中用到了两种动态代理来实现拦截切入功能:jdk 动态代理和 cglib 动态代理。两种方法同时存在,各有优劣。jdk 动态代理是由 java 内部的反射机制来实现的,cglib 动态代理底层则是借助 asm 来实现的。总的来说,反射机制在生成类的过程中比较高效,而 asm 在生成类之后的相关执行过程中比较高效(可以通过将 asm 生成的类进行缓存,这样解决 asm 生成类过程低效问题)。


下面我们分别来示例实现这两种方法。


2. JDK 动态代理


2.1 定义接口与实现类


image


上面代码定义了一个被拦截对象接口,即横切关注点。下面代码实现被拦截对象接口。


image


2.2 JDK 动态代理类


image


上述代码实现了动态代理类 JDKProxy,实现 InvocationHandler 接口,并且实现接口中的 invoke 方法。当客户端调用代理对象的业务方法时,代理对象执行 invoke 方法,invoke 方法把调用委派给 targetObject,相当于调用目标对象的方法,在 invoke 方法委派前判断权限,实现方法的拦截。


2.3 测试


image


结果如下:


image


3. CGLIB 字节码生成


3.1 要代理的类


CGLIB 既可以对接口的类生成代理,也可以针对类生成代理。示例中,实现对类的代理。


image


该类的实现和上面的接口实现一样,为了保持统一。


3.2 CGLIB 动态代理类


image


上述实现了创建子类的方法与代理的方法。getProxy(SuperClass.class)方法通过入参即父类的字节码,扩展父类的 class 来创建代理对象。intercept()方法拦截所有目标类方法的调用,obj 表示目标类的实例,method 为目标类方法的反射对象,args 为方法的动态入参,methodProxy 为代理类实例。method.invoke(targetObject, args)通过代理类调用父类中的方法。


3.3 测试


image


结果如下:


image


4. 总结


本文主要讲了 Spring Aop 动态代理实现的两种方式,并分别介绍了其优缺点。jdk 动态代理的应用前提是目标类基于统一的接口。如果没有该前提,jdk 动态代理不能应用。由此可以看出,jdk 动态代理有一定的局限性,cglib 这种第三方类库实现的动态代理应用更加广泛,且在效率上更有优势。


JDK 动态代理机制是委托机制,不需要以来第三方的库,只要要 JDK 环境就可以进行代理,动态实现接口类,在动态生成的实现类里面委托为 hanlder 去调用原始实现类方法;CGLib 必须依赖于 CGLib 的类库,使用的是继承机制,是被代理类和代理类继承的关系,所以代理类是可以赋值给被代理类的,如果被代理类有接口,那么代理类也可以赋值给接口。


参考


  1. jdk 动态代理代理与 cglib 代理原理探究

  2. AOP的底层实现-CGLIB动态代理和JDK动态代理


本文分享自华为云社区《还不懂 Spring AOP?一文带你搞懂动态代理》,原文作者:aoho 。


点击关注,第一时间了解华为云新鲜技术~


发布于: 2021 年 01 月 22 日阅读数: 551
用户头像

提供全面深入的云计算技术干货 2020.07.14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
一文带你搞懂从动态代理实现到Spring AOP