SpringBoot2.x中的AOP机制总结(附带demo)
寄语:刚开始学aop的时候是大三吧,老师讲的不好,我也没学好,导致现在才有个较为清晰的认知,那个时候只知道有aop,
根部不明白aop的作用,时至今日,任然觉得aop难以咀嚼,奈何平时不用面试要用,特此总结。
下面开始总结:
注意:我使用的是springboot2.1+maven3.6,请自行搭建基础环境
项目github地址:https://github.com/zgq7/devloper-mine/blob/master/src/main/java/com/dev/config/aop/BaseAop.java
1:导入maven依赖
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
2:创建一个class作为切面类,如下:
package com.dev.config.aop; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order; import java.util.Collections; /**
* Created by zgq7 on 2019/7/12.
*
* 各通知执行顺序:
* 1:around->
* 2:before->
* 3:around->retrun code ->
* 4:after->
* 5:afterReturning->
* 6:afterThrowing
* </p>
* <p>
* order 执行顺序:
* 1:进入目的方法时:order值越小越先执行
* 2:从目的方法出去时:order值越大越先执行
* </p>
*/
@Aspect
@Order(1)
public class BaseAop { private final Logger log = LoggerFactory.getLogger(this.getClass()); /**
* 写入具体切面点
*
* @apiNote execution 路径中的 "." 如果是精确到类,则一个就行,如果是精确到包就得两个 "."
* @apiNote execution 路径若只精确到包,就无法使用 before、after、afterReturuning、around 四个通知模块,启动会报错
**/
@Pointcut("execution(public * com.dev.controller.TestController.s())")
public void aspect() {
} /**
* 进入方法体前
**/
@Before(value = "aspect()")
public void before(JoinPoint joinPoint) {
log.info("before :参数类型:{}", joinPoint.getArgs());
} /**
* 该切面返回数据前(在retrun之前执行)
**/
@After(value = "aspect()")
public void after(JoinPoint joinPoint) {
log.info("aop before return :{}", joinPoint.toLongString());
} /**
* 该切面返回数据后
* joinPoint.getSignature() 返回方法放回类型 及 方法路径
**/
@AfterReturning(value = "aspect()", returning = "result")
public void afterReturning(Object result) {
log.info("aop after return :返回结果:{}", result);
} /**
* 环绕通知
* 1:before之前
* 2:afterReturning之后
*
* @apiNote 1:@Around 下接的方法的参数必须为 ProceedingJoinPoint 类型,
* @apiNote 2:proceedingJoinPoint.proceed() 产生的结果即为 @AfterReturning 中的 result,可 debug 调试
* @apiNote 3:由于@Around要提前获取到目的方法的执行结果,且@Around提前于@AfterThrowing运行,因此异常将在@Around中被捕获,从而导致@AfterThrowing捕获不到异常,因此@Around与@AfterThrowing混合使用
**/
//@Around(value = "aspect()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) {
log.info("aop arrounding :{}", proceedingJoinPoint.getSignature().getName());
try {
return proceedingJoinPoint.proceed();
} catch (Throwable throwable) {
log.info("aop arrounding error :{}", throwable.getMessage());
//throwable.printStackTrace();
return Collections.EMPTY_MAP;
}
} /**
* 切面报错
**/
@AfterThrowing(value = "aspect()", throwing = "exception")
public void afterThrowing(Throwable exception) {
log.error("exception occured , msg : {}", exception.getMessage());
if (exception instanceof NullPointerException)
log.info("空指针异常");
} }
notice2.1:多个aspect的执行顺序
1:进入目的方法时:order值越小越先执行
2:从目的方法出去时:order值越大越先执行

notice2.2:aspect 中 @befer、@after、@afterReturning、@around、@afterThrowing的执行顺序
* 1:around->
* 2:before->
* 3:around->retrun code ->
* 4:after->
* 5:afterReturning
notice2.2.1:各项通知也严格按照order的值进行传递一层一层的走下去
notice2.3:aspect 中@around 下属的方法必须要有返回值,否则就是一个 “有问题” 的切面
* @apiNote 1:@Around 下接的方法的参数必须为 ProceedingJoinPoint 类型,
* @apiNote 2:proceedingJoinPoint.proceed() 产生的结果即为 @AfterReturning 中的 result,可 debug 调试
notice2.4:aspect 中@around 不能与 @afterThrowing 混用
* @apiNote 3:由于@Around要提前获取到目的方法的执行结果,且@Around提前于@AfterThrowing运行,因此异常将在@Around中被捕获,从而导致@AfterThrowing捕获不到异常,因此@Around与@AfterThrowing混合使用
notice2.5:aspect 中@PointCut中的execution类路径或者包路径问题
* @apiNote execution 路径中的 "." 如果是精确到类,则一个就行,如果是精确到包就得两个 "."
* @apiNote execution 路径若只精确到包,就无法使用 before、after、afterReturuning、around 四个通知模块,启动会报错
写的不好或总结的不好望多多见谅,有错误请指出,免得误人子弟;
SpringBoot2.x中的AOP机制总结(附带demo)的更多相关文章
- 理解Django 中Call Stack 机制的小Demo
		
1.工作流程 request/response模式下,request并不是直接到达view方法,view方法也不是将返回的response直接发送给浏览器的,而是request由外到里的层层通过各种m ...
 - Castle框架中的IOC和AOP机制
		
反转控制(IOC)和面向切面编程(AOP)技术作为当前比较流行的技术,其优势已受到广泛关注,但是这两项新技术在实际项目上的应用研究却很落后,而且在.NET平台下实现这两项技术没有形成可以广泛套用的框架 ...
 - SpringBoot2.0中的事务@Transactional
		
在SpringBoot2.0中使用使用需要注意的地方. 1. 加@Transactional的方法不能是private和protected修饰,private会直接报编译错误,protected不会报 ...
 - .Net中的AOP系列之《拦截位置》
		
返回<.Net中的AOP>系列学习总目录 本篇目录 位置拦截 .Net中的字段和属性 PostSharp位置拦截 真实案例--懒加载 .Net中的懒加载 使用AOP实现懒加载 如何懒加载字 ...
 - 浅谈Linux中的信号处理机制(二)
		
首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号处理机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Lin ...
 - 【转】在.Net中关于AOP的实现
		
原文地址:http://www.uml.org.cn/net/201004213.asp 一.AOP实现初步 AOP将软件系统分为两个部分:核心关注点和横切关注点.核心关注点更多的是Domain Lo ...
 - [Spring-AOP-XML] 利用Spirng中的AOP和XML进行事务管理
		
Spring中的AOP进行事务管理有三种方式 A.自定义事务切面 利用AspectJ来编写事务,我们一般把这个切面作用在service层中.其他代码在下面 编写一个Transaction实现类,通过S ...
 - Spring框架中的AOP技术----配置文件方式
		
1.AOP概述 AOP技术即Aspect Oriented Programming的缩写,译为面向切面编程.AOP是OOP的一种延续,利用AOP技术可以对业务逻辑的各个部分进行隔离,从使得业务逻辑各部 ...
 - 【Java基础】java中的反射机制与动态代理
		
一.java中的反射机制 java反射的官方定义:在运行状态下,可以获取任意一个类的所有属性和方法,并且可通过某类任意一对象实例调用该类的所有方法.这种动态获取类的信息及动态调用类中方法的功能称为ja ...
 
随机推荐
- Eclipse配置MySQL连接工具
			
1.项目名称右键新建文件夹lib 2.用鼠标将mysql-connector-java-5.1.15-bin.jar移动到lib文件夹中 3.选择Copy files点击OK 4.右键移动过来的mys ...
 - java大数函数(附官方文档链接)
			
java文档 字段摘要 static BigInteger ONE BigInteger 的常量 1. static BigInteger TEN BigInt ...
 - B. Modular Equations
			
Last week, Hamed learned about a new type of equations in his math class called Modular Equations. L ...
 - 使用eclipse搭建第一个java web应用
			
一. 首先是eclipse得下载,你要下载Eclipse IDE for Java EE这种类型的,我之前下载的Eclipse IDE for Enterprise Java Developers是官 ...
 - hdu2126 Buy the souvenirs
			
Problem Description When the winter holiday comes, a lot of people will have a trip. Generally, ther ...
 - meterpreter php payload && windows payload 学习
			
一 情景 本地kali linux 192.168.1.2 目标 windows NT 服务器192.168.1.4 目的是获取shell 二 过程 首先在linux建立终端 ,msfconsole ...
 - 信号量解决理发师问题(barber)
			
问题描述及思路 代码 一些细节见注释 这里ret应该用int..忘了改了. 运行结果 因为座位数和到来最大间隔的原因,没有出现全部椅子被占用的情况
 - codeforces 758D
			
D. Ability To Convert time limit per test 1 second memory limit per test 256 megabytes input standar ...
 - C# 类 (1)
			
通常每个类都会单独定义在自己的文件里,方便区分 Class 里面定义了 变量 属性 方法 实例化这个Class,得到一个对象,然后可以使用这个对象的变量 属性和方法 属性 Properties 像是一 ...
 - axios增加自定义headers,页面上出现,服务端收不到
			
问题 axios增加自定义headers,页面上出现,服务端收不到 原因 vue-cli起的服务是用node-http-proxy中间件处理的 默认是只有几个常用的header,自定义header是直 ...