Spring AOP之初探黄龙

简介: Spring AOP之初探黄龙

1F什么是AOP


AOP(Aspect Oriented Programming),即面向切面编程,对于面向对象编程(OOP)来说,AOP是一种补充。面向对象编程是软件开发的最基本抽象思想,OOP使得代码脱离了面向过程这种高耦合的代码开发模式,同时OOP引入了封装、继承、多态等概念建立了一种纵向依赖关系,从代码复用的角度看,OOP复用了同一继承链上的代码,也就是说OOP是纵向代码复用,无法横向代码复用。OOP的缺陷导致了很多公共代码需要重复引用重复编写,这也是Java项目工程中常常需要封装很多静态类、公共类的原因,但对于Java程序员来说这不是一件很正常的事情吗?就像吃饭要用筷子夹,喝汤要用勺子舀一样。而AOP的思想却是关注横向切面,相当于在纵向关系链中横切一刀,将那些业务模块的公共调用代码封装起来,形成一个切面(Aspect),从而减少了公共代码的引用点,提高了可维护性。下图是小编绘制的一副AOP与OOP关系的小图:

image.png

很多小伙伴问AOP适合应用于什么样的场景?关于这个问题,网上有回答大部分都是权限认证、日志、事务、监控等场景,其实在小编看来,AOP是一种横向关注思想,可以说是一种基本的开发技巧,并不局限于某些特定的应用场景,只要在系统中,从横向角度可以看到有代码优化与简洁的空间,那就能用AOP技术来改善代码。这里小编始终在强调两个字:横向!的确,AOP开发最重要的指导思想就是角度,而最重要的观察角度就是横向(就像上图中小编画的程序员的眼睛那样观察)。关于AOP的理解,忆蓉之心说他一直把AOP看做”刀与豆腐的关系,哪里不爽,就切一刀“,的确这种横切一刀很形象的表达了AOP两个重要元素:横向与切面。其实过滤器技术(filter)即可看成面向切面的一种开发思想,只是过滤器一般应用于特定场景,不具备通用性。本片小编带大家一起探讨一下Spring 中对于AOP的通用支持 -- Spring AOP。


2FSpring AOP


Java中AOP的实现分为了基于AspectJ实现的静态织入与Spring支持的动态代理织入技术。ApectJ的原理主要是通过控制Java的编译时机,将切面增强代码直接编译入生成的class文件中,其效率较高,但入侵性强;而Spring AOP的动态织入主要依赖于JDK动态代理与CGLIB的动态代理来实现,相对于ApectJ绿色环保,但效率相对较低。(关于动态与静态的具体原理,以及一些剖析将在下一篇中详细讨论,本文主要让小伙伴们先初步认识一下Spring AOP的使用方式)。在项目中引用Spirng AOP也非常方便,通过Maven就可以简单的引入Spring AOP依赖的包了:

image.png

OK现在,我们就可以开始使用AOP来在项目中进行切面开发了。但是在开发前,需要理解一下AOP开发中的一些流程。其实引入Spring后,AOP开发非常简单,程序员只需要根据具体的业务逻辑定义切入点,然后程序员就只需要关注该切入点的增强处理逻辑(Advice)开发工作即可,然后剩余的工作就都交给AOP框架去自动实现了,Spring AOP框架会根据代理的切入点定义自动生成代理对象,而代理对象的方法便是增强处理加上被代理(目标)对象的方法的“总和”。AOP织入后,代理类与被代理类的关系可以抽象如下图所示的关系:


image.png

其实,AOP技术的思想与实现非常像作者之前从事C++开发中用到的Hook技术,其本质都通过对目标对象的代理,从而达到对目标对象调用的监控与扩展,只是实现的具体技术与方式有些区别罢了。所以在开发这个领域来说,很多技术都是相通的,多领会一门语言技巧,或许会为你多增加一个看待编程的角度。


3FSpring AOP的使用


好了,这里我们就可以开始使用Spring AOP来进行切面开发了,首先我们准备一个用于测试的服务类接口与服务实现,如下:

image.png

万事俱备,我们可以定义一个用于监控Service包下所有函数调用的监控切面,这里我们使用前置增强(Before)来实现对应的功能。代码如下:

image.png

好了,此时,我们就对 service包下的所有类的,所有函数调用进行了前置增强,在增强逻辑中我们只简单打印出增强的函数名称,运行结果如下:

image.png

说明Before增强逻辑被成功调用,也意味着我们使用的Spring AOP的增强处理生效了。


4FAOP切入时机之增强处理

上一节我们已经开发了前置增强处理,实际上Spring几乎支持了函数级别调用的所有环节的增强处理,常用的增强处理有 @Before、@After、@Around、@AfterReturning、@AfterThrowing 这5种增强,分别对应于被代理目标函数调用的 前置、后置、返回、异常返回、包含 这5种增强处理模式,这5种增强处理为AOP开发提供了全面的切入时机的支持,并且使用方式也非常统一,与上节Before增强的编写几乎相同:

image.png

这里我们再用一张更直观的图,来看看增强逻辑与代理目标函数的关系:

image.png

5FAOP的切入点


从上节开始,小伙伴基本上就能利用Spring AOP进行切面开发了。但是一定存在疑问,为何所有注解中都声明了这样的语句,如下:

execution(*com.znlover.spring.aop.sample.service.*.*(..))

这是什么鬼,这是AOP切入点的表达式语句,而Spring AOP表达式语句是从静态织入AOP框架ApectJ的表达式语法继承来的(完全相同)。具体全面的语法规则,小伙伴可以查阅相关资料,这里我们解读一下最常用的execution表达式语法,如下图所示:

image.png

此外,Spring AOP 还支持通@Pointcut定义一个通用的切入点,这样就可以在其他增强注解中以名称的方式使用该切入点,从而避免了多出重复编写表达式语句:

image.png


6F增强处理连接点JoinPoint


通过上面的篇章,小伙伴应该对于切面有了一个初步的理解,但是还有一点这里需要说明一下,那就是增强处理的连接点JoinPoint,当该增强处理方法被调用时,JoinPoint 参数就代表了织入增强处理的连接点,通过JoinPoint增强处理可以获取到目标函数的相关信息,JoinPoint 里包含了如下几个常用方法。

  • Object[] getArgs(): 返回执行目标方法时的参数。
  • Signature getSignature(): 返回被增强的方法的相关信息。
  • Object getTarget(): 返回被织入增强处理的目标对象。
  • Object getThis(): 返回 AOP 框架为目标对象生成的代理对象。

注意:当时使用 Around 处理时,我们需要将第一个参数定义为ProceedingJoinPoint 类型,该类型是 JoinPoint 类型的子类。JoinPoint在AOP编程中基本是必要的一个参数,尤其在监控,参数过滤的使用场景下。



本节初步向小伙伴们展示了Java项目中集成Spring AOP的方法,可以发现,AOP开发中,自始至终对于被代理类都没有做出任何需要配合改变的地方,这就是AOP的魅力,一方面体现了AOP系统解耦构建的强大功力,另一方面也体现了AOP更适合于扩展与公共组件的开发,因此AOP已经是Java生态体系中的一项重要技术。当然依照本公众号的刨根问底的行文习惯,本片不会是结束,只是探讨AOP开发的开端,希望还没有了解过AOP相关知识的小伙伴,借此跟着我们一起踏上深挖AOP的探索之路!


相关文章
|
3月前
|
Java
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
这篇文章是Spring5框架的实战教程,深入讲解了AOP的基本概念、如何利用动态代理实现AOP,特别是通过JDK动态代理机制在不修改源代码的情况下为业务逻辑添加新功能,降低代码耦合度,并通过具体代码示例演示了JDK动态代理的实现过程。
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
|
8天前
|
XML Java 数据安全/隐私保护
Spring Aop该如何使用
本文介绍了AOP(面向切面编程)的基本概念和术语,并通过具体业务场景演示了如何在Spring框架中使用Spring AOP。文章详细解释了切面、连接点、通知、切点等关键术语,并提供了完整的示例代码,帮助读者轻松理解和应用Spring AOP。
Spring Aop该如何使用
|
28天前
|
存储 缓存 Java
Spring高手之路23——AOP触发机制与代理逻辑的执行
本篇文章深入解析了Spring AOP代理的触发机制和执行流程,从源码角度详细讲解了Bean如何被AOP代理,包括代理对象的创建、配置与执行逻辑,帮助读者全面掌握Spring AOP的核心技术。
35 3
Spring高手之路23——AOP触发机制与代理逻辑的执行
|
13天前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
27 1
|
9天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
22 0
|
2月前
|
设计模式 Java 测试技术
spring复习04,静态代理动态代理,AOP
这篇文章讲解了Java代理模式的相关知识,包括静态代理和动态代理(JDK动态代理和CGLIB),以及AOP(面向切面编程)的概念和在Spring框架中的应用。文章还提供了详细的示例代码,演示了如何使用Spring AOP进行方法增强和代理对象的创建。
spring复习04,静态代理动态代理,AOP
|
1月前
|
Java 编译器 Spring
Spring AOP 和 AspectJ 的区别
Spring AOP和AspectJ AOP都是面向切面编程(AOP)的实现,但它们在实现方式、灵活性、依赖性、性能和使用场景等方面存在显著区别。‌
65 2
|
1月前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
【10月更文挑战第1天】Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
126 9
|
1月前
|
XML Java 数据格式
Spring的IOC和AOP
Spring的IOC和AOP
45 0
|
2月前
|
Java 数据库连接 数据库
Spring基础3——AOP,事务管理
AOP简介、入门案例、工作流程、切入点表达式、环绕通知、通知获取参数或返回值或异常、事务管理
Spring基础3——AOP,事务管理