看了这篇文章,如果你还是不会用AOP来写程序,请你打我!! =.=|||

引言

Spring AOP是一个对AOP原理的一种实现方式,另外还有其他的AOP实现如AspectJ等。

AOP意为面向切面编程,是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,是OOP面向对象编程的一种补足。它是软件开发中的一个热点技术,Spring AOP 也是Spring框架的核心特性之一(另一个核心特性是IOC)。

通过AOP技术,我们希望实现一种通用逻辑的解耦,解决一些系统层面上的问题,如日志、事务、权限等,从而提高应用的可重用性和可维护性,和开发效率。

Struts2的拦截器设计就是基于AOP的思想,是非常经典的理论实践案例。

重要概念

AOP中包括 5 大核心概念:切面(Aspect)、连接点(JoinPoint)、通知(Advice)、切入点(Pointcut)、AOP代理(Proxy)。(记忆口诀:通知 代理 厨师两点(连接点切入点)切面包。)

关于前面四点,将会直接涉及到相关编码的实现方式,因此将会结合代码进行解释,在这里简单阐述一下AOP代理。

AOP代理,是AOP框架如Spring AOP创建的对象,代理就是对目标对象进行增强,Spring AOP中的代理默认使用JDK动态代理,同时支持CGLIB代理,前者基于接口,后者基于子类。在Spring AOP中,其功能依然离不开IOC容器,代理的生成、管理以及其依赖关系都是由IOC容器负责,而根据目前的开发提倡“面向接口编程”,因此大多使用JDK动态代理。

五大通知类型

1、前置通知 [ Before advice ] :在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常;

2、正常返回通知 [ After returning advice ] :在连接点正常执行完成后执行,如果连接点抛出异常,则不会执行

3、异常返回通知 [ After throwing advice ] :在连接点抛出异常后执行

4、返回通知 [ After (finally) advice ] :在连接点执行完成后执行,不管正常执行完成,还是抛出异常,都会执行返回通知中的内容;

5、环绕通知 [ Around advice ] :环绕通知围绕在连接点前后,比如一个方法调用的前后。这种通知是最强大的通知,能在方法调用前后自定义一些操作。

应用案例分析

在OOP中的基本单元是类,而在AOP中的基本单元是Aspect,它实际上也是一个类,只不过这个类用于管理一些具体的通知方法和切入点。

所谓的连接点,实际上就是一个具体的业务方法,比如Controller中的一个请求方法,而切入点则是带有通知的连接点,在编程时主要体现为书写切入点表达式,这个表达式将会定义一个连接点。

就以Controller中的一个请求方法为例,通过AOP的方式实现一定的业务逻辑。

这个逻辑是:GET请求某一方法,然后通过一个Aspect来实现在这个方法调用前和调用后做一些日志输出处理。

1、引入依赖jar包

基于spring boot 的maven依赖如下,如果是仅使用spring框架的话,请参考其他资料:

2、定义业务方法(连接点)

这个方法就是后面AOP切面中的那个连接点,方法非常简单,仅仅接收一个姓名性别,并输出 “某某做作业......” :

3、定义切面类、定义切入点及通知方法

下面的代码中,@Aspect、@Pointcut、@Component都是必须的(@Component用于将这个切面类注入到 IOC容器中,如果不用@Component就用@Bean的方式也是可以的,但总之切面类必须被注入到 IOC容器中,这也就是前面说的Spring AOP不能脱离IOC容器的体现)。而@Before用来定义一个前面提到过的五大通知类型中的 Before advice类型的通知方法,这个根据具体的需要可以进行选择。

@Pointcut注解的参数是一个表达式,可以当做是一个固定的写法,“ * ” 表示任意返回值,“ .. ” 也是一种通配。当然,方法的全名可以使用编辑器的复制功能,具体关于execution表达式的说明,在此不做展开讨论。

再简单说一下通过RequestContextHolder这个最终获取request的操作,就当是一个固定写法,可以从请求上下文中拿到当前的请求对象,并从请求中获得一些信息,更详细的API用法不做展开。

4、执行结果

启动项目,浏览器地址栏输入:

控制台显示如下:

可以从输出结果中看到,在执行doHomeWork(String name, Gender gender) 方法之前先执行了切面类中定义的beforeHomeWork()方法,成功的完成了在切入点之前执行一个操作的需要。这就是Spring AOP的典型应用。

环绕通知实现

在上一节“应用案例分析”中介绍了Before advice的使用方式,而Spring AOP的通知类型有五种,在Spring 框架里分别有对应的注解来代表每一种通知类型,它们分别是:

@Before 对应——>前置通知 [ Before advice ]

@AfterReturning 对应——>正常返回通知 [ After returning advice ]

@AfterThrowing 对应——>异常返回通知 [ After throwing advice ]

@After 对应——>返回通知 [ After (finally) advice ]

@Around 对应——>环绕通知 [ Around advice ]

其中,前四种通知类型,与@Before的使用完全相同,根据各自不同的使用定义自行选择。

需要说明的是@Around的使用。在定义环绕通知方法的时候,需要传入一个org.aspectj.lang.ProceedingJoinPoint 对象:

执行结果如下:

根据输出结果,我们注意到了一个问题,即@Around先于@Before通知执行。这就引出了一个非常重要的问题,即各类型通知执行的先后顺序。

各类型通知执行先后顺序

在实际开发中,有时候我们会针对同一个切入点进行多种Aspect包装,比如,可以有一个Aspect管理对一个方法进行日志打印的通知,而另一个Aspect管理对这个方法的一些校验工作。因此,涉及到两类问题:

1、同一个切入点不同通知的执行顺序

2、同一个切入点不同切面的执行顺序

我们在前面的“环绕通知实现”结果中看到,@Around是先于@Before执行的,这就是其中一个问题的引出,即同一个切入点不同通知的执行顺序。来看下面这张图:

可以看到Aspect1 和Aspect2两个切面类中所有通知类型的执行顺序,Method是具体的切入点,order代表优先级,它根据一个int值来判断优先级的高低,数字越小,优先级越高!所以,不同的切面,实际上是环绕于切入点的同心圆:

---欢迎关注“Java圣斗士”,我是你们的小可爱(✪ω✪)---

---专注IT职场经验与IT技术分享的灵魂导师---

---期待与您的互动哦!---

springaop事务逻辑原理_搞懂Spring AOP,这一篇就够了相关推荐

  1. springaop事务逻辑原理_太狠了!阿里大牛手写的Spring核心面试笔记:IOC+AOP+MVC+事务...

    Spring作为现在最流行的java 开发技术,其内部源码设计非常优秀.如果你不会Spring,那么很可能面试官会让你回家等通知. Spring是什么? 有一个工地,几百号人在用铁锹铲子挖坑. 如果开 ...

  2. springaop事务逻辑原理_架构师:一篇文章掌握——Spring 事务管理

    对大多数Java开发者来说,Spring事务管理是Spring应用中最常用的功能,使用也比较简单.本文主要逐步介绍Spring事务管理的相关知识点及原理,作为Spring事务管理的学习总结. 一.关键 ...

  3. hashmap 允许key重复吗_搞懂 HashMap,这一篇就够了

    HashMap 概述 「如果你没有时间细抠本文,可以直接看 HashMap 概述,能让你对 HashMap 有个大致的了解」. HashMap 是 Map 接口的实现,HashMap 允许空的 key ...

  4. 一下子搞懂JDBC,看这篇就够了--以MySQL为例。

    一下子搞懂JDBC,看这篇就够了–以MySQL为例. 文章目录 一下子搞懂JDBC,看这篇就够了--以MySQL为例. 一.什么是JDBC? 二.JDBC的使用步骤 三.jdbc进阶--上述各个类或接 ...

  5. 一文搞懂Spring AOP源码底层原理

    一.什么是AOP 与OOP对比,AOP是处理一些横切性问题,这些横切性问题不会影响到主逻辑实现的,但是会散落到代码的各个部分,难以维护.一键获取源码地址spring aop面试题 AOP就是把这些问题 ...

  6. Java的反射机制,内含超简单实例代码(搞懂反射,这一篇就够了)

    一 首先来说说反射机制的概念: 程序在运行时, 对于类来说,可以知道该类的任意属性和方法: 对于对象来说,可以调用该对象的任意方法和属性: 就以上这种动态获取信息的机制就称为Java的反射机制 彻底了 ...

  7. python协程详解_彻底搞懂python协程-第一篇(关键词1-4)

    任何复杂的概念或系统都不是凭空出现的,我们完全可以找到它的演化历程,寻根究底终会发现,其都是在一系列并不那么复杂的简单组件上发展演化而来! by 落花僧 本文通过一系列关键概念,逐步递进理解协程. 0 ...

  8. 一张图搞懂Spring bean的完整生命周期

    转载自 一张图搞懂Spring bean的完整生命周期 一张图搞懂Spring bean的生命周期,从Spring容器启动到容器销毁bean的全过程,包括下面一系列的流程,了解这些流程对我们想在其中任 ...

  9. 轻轻松松看懂Spring AOP源码

    轻轻松松看懂Spring AOP源码 https://baijiahao.baidu.com/s?id=1596466083334197175&wfr=spider&for=pc 如果 ...

最新文章

  1. LeetCode简单题之差的绝对值为 K 的数对数目
  2. 星期和工作日计算,你会了吗?
  3. C++继承中的构造与析构
  4. 汇编层探索与讨论c++引用
  5. 分式的二阶导数怎么求_为何二阶微分要记为 d²y/dx²?
  6. unix grep命令的大致实现
  7. Objective -C Memory Management 内存管理 第一部分
  8. 聊一聊对外API接口的存活检查可以怎么做
  9. 线程下的udp和tcp局域网聊天
  10. C#多线程编程系列(五)- C# ConcurrentBag的实现原理
  11. Android官方开发文档Training系列课程中文版:布局性能优化之ListView的优化
  12. Javascript是最好的编程语言吗?
  13. 解决:My97DatePicker 日期插件引用在PHP文件中maxDate和minDate控制失效问题
  14. [转]java 输出流转输入流
  15. 使用wepy 小程序授权点击取消授权失败的方案
  16. KITTI数据集简介与使用
  17. 元宇宙的车,迷你世界上不了
  18. 名词解释微型计算机,微机原理名词解释
  19. 浏览器的窗口大小被改变时触发的事件window.onresize
  20. 建立一个网站的具体过程

热门文章

  1. kafka学习_Kafka学习笔记下
  2. http抓包实战 pdf_实战 Wireshark https 抓包 2, 再抓 Moka 蹭 OurATS 的小尾巴
  3. python批量修改word特定位置的内容_利用python批量修改word文件名的方法示例
  4. 教你一秒分辨真假芯片!
  5. 蓝牙:为啥叫“蓝”牙,不叫“白”牙?
  6. 「第三篇」全国电子设计竞赛,这些你必须知道的比赛细节,文末附上近十年电赛题目下载...
  7. HDLBits答案(14)_Verilog有限状态机(1)
  8. python开发笔记软件_图解Python编程神器Jupyter Notebook
  9. python导出数据找不到csv_python – 将数据从neo4j导出到csv而不是json
  10. 小皮面板phpstudy的MYSQL服务无法启动_ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost‘ (10061)