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的探索之路!


相关文章
|
21天前
|
XML 安全 Java
使用 Spring 的 @Aspect 和 @Pointcut 注解简化面向方面的编程 (AOP)
面向方面编程(AOP)通过分离横切关注点,如日志、安全和事务,提升代码模块化与可维护性。Spring 提供了对 AOP 的强大支持,核心注解 `@Aspect` 和 `@Pointcut` 使得定义切面与切入点变得简洁直观。`@Aspect` 标记切面类,集中处理通用逻辑;`@Pointcut` 则通过表达式定义通知的应用位置,提高代码可读性与复用性。二者结合,使开发者能清晰划分业务逻辑与辅助功能,简化维护并提升系统灵活性。Spring AOP 借助代理机制实现运行时织入,与 Spring 容器无缝集成,支持依赖注入与声明式配置,是构建清晰、高内聚应用的理想选择。
254 0
|
5月前
|
监控 安全 Java
Spring AOP实现原理
本内容主要介绍了Spring AOP的核心概念、实现机制及代理生成流程。涵盖切面(Aspect)、连接点(Join Point)、通知(Advice)、切点(Pointcut)等关键概念,解析了JDK动态代理与CGLIB代理的原理及对比,并深入探讨了通知执行链路和责任链模式的应用。同时,详细分析了AspectJ注解驱动的AOP解析过程,包括切面识别、切点表达式匹配及通知适配为Advice的机制,帮助理解Spring AOP的工作原理与实现细节。
|
2月前
|
人工智能 监控 安全
Spring AOP切面编程颠覆传统!3大核心注解+5种通知类型,让业务代码纯净如初
本文介绍了AOP(面向切面编程)的基本概念、优势及其在Spring Boot中的使用。AOP作为OOP的补充,通过将横切关注点(如日志、安全、事务等)与业务逻辑分离,实现代码解耦,提升模块化程度、可维护性和灵活性。文章详细讲解了Spring AOP的核心概念,包括切面、切点、通知等,并提供了在Spring Boot中实现AOP的具体步骤和代码示例。此外,还列举了AOP在日志记录、性能监控、事务管理和安全控制等场景中的实际应用。通过本文,开发者可以快速掌握AOP编程思想及其实践技巧。
|
2月前
|
人工智能 监控 安全
如何快速上手【Spring AOP】?核心应用实战(上篇)
哈喽大家好吖~欢迎来到Spring AOP系列教程的上篇 - 应用篇。在本篇,我们将专注于Spring AOP的实际应用,通过具体的代码示例和场景分析,帮助大家掌握AOP的使用方法和技巧。而在后续的下篇中,我们将深入探讨Spring AOP的实现原理和底层机制。 AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的核心特性之一,它能够帮助我们解决横切关注点(如日志记录、性能统计、安全控制、事务管理等)的问题,提高代码的模块化程度和复用性。
|
2月前
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
|
9月前
|
XML Java 开发者
Spring Boot中的AOP实现
Spring AOP(面向切面编程)允许开发者在不修改原有业务逻辑的情况下增强功能,基于代理模式拦截和增强方法调用。Spring Boot通过集成Spring AOP和AspectJ简化了AOP的使用,只需添加依赖并定义切面类。关键概念包括切面、通知和切点。切面类使用`@Aspect`和`@Component`注解标注,通知定义切面行为,切点定义应用位置。Spring Boot自动检测并创建代理对象,支持JDK动态代理和CGLIB代理。通过源码分析可深入了解其实现细节,优化应用功能。
419 6
|
8月前
|
XML Java 测试技术
Spring AOP—通知类型 和 切入点表达式 万字详解(通俗易懂)
Spring 第五节 AOP——切入点表达式 万字详解!
373 25
|
8月前
|
XML 安全 Java
Spring AOP—深入动态代理 万字详解(通俗易懂)
Spring 第四节 AOP——动态代理 万字详解!
279 24
|
7月前
|
Java API 微服务
微服务——SpringBoot使用归纳——Spring Boot中的切面AOP处理——Spring Boot 中的 AOP 处理
本文详细讲解了Spring Boot中的AOP(面向切面编程)处理方法。首先介绍如何引入AOP依赖,通过添加`spring-boot-starter-aop`实现。接着阐述了如何定义和实现AOP切面,包括常用注解如`@Aspect`、`@Pointcut`、`@Before`、`@After`、`@AfterReturning`和`@AfterThrowing`的使用场景与示例代码。通过这些注解,可以分别在方法执行前、后、返回时或抛出异常时插入自定义逻辑,从而实现功能增强或日志记录等操作。最后总结了AOP在实际项目中的重要作用,并提供了课程源码下载链接供进一步学习。
756 0
|
7月前
|
Java 开发者 微服务
微服务——SpringBoot使用归纳——Spring Boot中的切面AOP处理——什么是AOP
本文介绍了Spring Boot中的切面AOP处理。AOP(Aspect Oriented Programming)即面向切面编程,其核心思想是分离关注点。通过AOP,程序可以将与业务逻辑无关的代码(如日志记录、事务管理等)从主要逻辑中抽离,交由专门的“仆人”处理,从而让开发者专注于核心任务。这种机制实现了模块间的灵活组合,使程序结构更加可配置、可扩展。文中以生活化比喻生动阐释了AOP的工作原理及其优势。
358 0