热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SpringAOP的简介与使用

什么是面向切面编程AOP是一种编程范式,并非是Spring的独创,它与语言无关,是一种编程思想。AOP可以帮助我们将通用的逻辑从业务逻辑中

什么是面向切面编程

AOP 是一种编程范式,并非是 Spring 的独创,它与语言无关,是一种编程思想。AOP 可以帮助我们将通用的逻辑从业务逻辑中分离出来。从项目角度来讲,有一些逻辑散布于程序的各个地方,但它们的逻辑又是千篇一律的相同。比如:我们需要打印每个请求的 URL、请求参数、IP地址,最简单的做法是在每一个 Controller 中去打印出这些信息。如果使用 AOP,我们能够更加轻松的处理这些问题。打印日志并不是使用 AOP 的唯一场景,我们还可以通过切面去统一处理 声明式事务、缓存、应用安全 等等。

AOP 相关术语

AOP 作为一种编程范式,已经衍生出了术语它的一些相关术语,例如:切面、通知、连接点、织入 等等。为了更好的理解如何在 Spring 中使用 AOP,我们必须对这些术语有一定的认知。

通知(Advice)

Spring AOP 支持五种类型的通知,它们分别定义了切面在什么时候使用,以及定义了切面需要做些什么。

  • @Before 前置通知,目标方法被调用之前执行
  • @After 后置通知,目标方法完成之后执行
  • @AfterReturning 返回通知,目标方法执行成功(未抛出异常)之后执行
  • @AfterThrowing 异常通知,目标方法执行失败(抛出异常)之后执行
  • @Around 环绕通知,目标方法执行前后都会调用

连接点(JoinPoint)

程序执行的某个特定位置:如类开始初始化前、类初始化后、类某个方法调用前、调用后、方法抛出异常后。一个类或一段程序代码拥有一些具有边界性质的特定点,这些点中的特定点就称为 "连接点"。Spring 仅支持方法的连接点,即仅能在方法调用前、方法调用后、方法抛出异常时以及方法调用前后这些程序执行点织入增强。连接点由两个信息确定:第一是用方法表示的程序执行点,第二是用相对点表示的方位。

切点(Poincut)

每个程序类都拥有多个连接点,如一个拥有两个方法的类,这两个方法都是连接点,即连接点是程序类中客观存在的事物。AOP 通过 "切点" 定位特定的连接点。连接点相当于数据库中的记录,而切点相当于查询条件。切点和连接点不是一对一的关系,一个切点可以匹配多个连接点。在 Spring 中,切点通过 org.springframework.aop.Pointcut 接口进行描述,它使用类和方法作为连接点的查询条件,Spring AOP 的规则解析引擎负责切点所设定的查询条件,找到对应的连接点。其实确切地说,不能称之为查询连接点,因为连接点是方法执行前、执行后等包括方位信息的具体程序执行点,而切点只定位到某个方法上,所以如果希望定位到具体连接点上,还需要提供方位信息。

切面(Aspect)

切面由切点和增强(引介)组成,它既包括了横切逻辑的定义,也包括了连接点的定义,Spring AOP 就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中。

引入(Introduction)

引入使我们具备了为类添加一些属性和方法的能力。这样,即使一个业务类原本没有实现某个接口,通过 AOP 的引介功能,我们可以动态地为该业务类添加接口的实现逻辑,让业务类成为这个接口的实现类。

织入(Weaving)

织入是将增强添加对目标类具体连接点上的过程。AOP 像一台织布机,将目标类、增强或引介通过 AOP 这台织布机天衣无缝地编织到一起。根据不同的实现技术,AOP 有三种织入的方式:1. 编译期织入,这要求使用特殊的Java编译器。2. 类装载期织入,这要求使用特殊的类装载器。3. 动态代理织入,在运行期为目标类添加增强生成子类的方式。Spring 采用动态代理织入,而 AspectJ 采用编译期织入和类装载期织入。

代理(Proxy)

一个类被 AOP 织入增强后,就产出了一个结果类,它是融合了原类和增强逻辑的代理类。根据不同的代理方式,代理类既可能是和原类具有相同接口的类,也可能就是原类的子类,所以我们可以采用调用原类相同的方式调用代理类。

AspectJ 切点表达式

Spring 只支持方法级别的连接点,切点表达式可以通过 execution 来定义。比如:@Pointcut(value = "execution(* com.vincent.springframework.example.Controller.*(..))") 表示匹配 com.vincent.springframework.example.Controller 这个类下面全部的方法。 关于 AspectJ 的 execution 表达式的详细信息,可以查看这篇文章 Spring AspectJ 的 execution表达式

添加 AsepctJ 的依赖

<dependency><groupId>org.aspectjgroupId><artifactId>aspectjweaverartifactId><version>1.9.1version>
dependency>

使用 XML 定义切面

在配置文件中创建切面&#xff0c;需要通过 Spring 的 aop 命名空间来开启。


<aop:aspectj-autoproxy/>

<content:component-scan base-package&#61;"com.vincent.spring.framework.example"/>

<bean id&#61;"messageService" class&#61;"com.vincent.spring.framework.example.MessageService"/>

<bean id&#61;"messageAspect" class&#61;"com.vincent.spring.framework.example.MessageAspect"/>

<aop:config><aop:aspect id&#61;"messageAspect" ref&#61;"messageAspect"><aop:before method&#61;"beforeAction" pointcut&#61;"execution(* com.vincent.spring.framework.example.MessageService.call(..))"/><aop:before method&#61;"afterAction" pointcut&#61;"execution(* com.vincent.spring.framework.example.MessageService.call(..))"/>aop:aspect>
aop:config>

使用 Java 配置定义切面

&#64;Configuration
&#64;EnableAspectJAutoProxy
&#64;ComponentScan(basePackage &#61; "com.vincent.spring.framework.example")
public class AspectJConfig {
}

&#64;Aspect
public class MessageAspect {// 目标方法执行之前&#64;Pointcut("execution(* com.vincent.spring.framework.example.MessageService.call(..))")public void beforeAction() {System.out.println("before action");}// 目标方法执行之后&#64;Pointcut("execution(* com.vincent.spring.framework.example.MessageService.call(..))")public void afterAction() {System.out.println("after action");}
}



推荐阅读
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文介绍了作者在开发过程中遇到的问题,即播放框架内容安全策略设置不起作用的错误。作者通过使用编译时依赖注入的方式解决了这个问题,并分享了解决方案。文章详细描述了问题的出现情况、错误输出内容以及解决方案的具体步骤。如果你也遇到了类似的问题,本文可能对你有一定的参考价值。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 突破MIUI14限制,自定义胶囊图标、大图标样式,支持任意APP
    本文介绍了如何突破MIUI14的限制,实现自定义胶囊图标和大图标样式,并支持任意APP。需要一定的动手能力和主题设计师账号权限或者会主题pojie。详细步骤包括应用包名获取、素材制作和封包获取等。 ... [详细]
author-avatar
小老特
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有