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 ...
随机推荐
- xLua热更新插件
一.xLua插件下载安装 1.从GitHub上搜索并下载插件 2.将文件复制到unity中 3.检查是否有错误 二.在unity中调用lua 1.简单调用 在c#脚本中使用LuaEnv类可以运行lua ...
- B - Power Strings
Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc&quo ...
- CTGU_训练实录
前言 之前做题都没有感觉,慢慢出去比赛后,打Codeforces,看别的人博客,知乎上的讨论,慢慢的对算法有一些自己的思考.特写是最近看知乎上别人说的Dijkstra利用水流去理解,LCA的学习,感觉 ...
- poj2001 Shortest Prefixes (trie树)
Description A prefix of a string is a substring starting at the beginning of the given string. The p ...
- Codeforces Round #667 (Div. 3) D. Decrease the Sum of Digits (贪心)
题意:给你一个正整数\(n\),每次可以对\(n\)加一,问最少操作多少次是的\(n\)的所有位数之和不大于\(s\). 题解:\(n\)的某个位置上的数进位,意味这后面的位置都可以被更新为\(0\) ...
- 牛客编程巅峰赛S1第5场 - 青铜&白银 A.凯撒密码(字符串)
题意:给你一个加密的字符串,以及偏移量,求对应的明文. 题解:根据样例,不难看出模板串是:\(0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopq ...
- 牛客编程巅峰赛S1第3场 - 青铜&白银 C.牛牛晾衣服(二分)
题意:有\(n\)件衣服,每件衣服都有\(a_{i}\)滴水,所有衣服每分钟都能自然烘干\(1\)滴水,或者用烘干机,每分钟可以烘干\(k\)滴水,问最快多少分钟可以使所有衣服都烘干. 题解:这题和之 ...
- [APUE] 进程控制
APUE 一书的第八章学习笔记. 进程标识 大家都知道使用 PID 来标识的. 系统中的一些特殊进程: PID = 0: 调度进程,也称为交换进程 (Swapper) PID = 1: init 进程 ...
- [Python] Pandas的delete、drop函数的用法
目录 drop函数 Axis(轴)含义 drop用法实验 delete函数 drop函数 DataFrame.drop(labels=None, axis=0, index=None, columns ...
- C# 类 (7) - 抽象 Abstract
Abstract 抽象类,关键字Abstract ,最典型的应用就是在 继承机制里 作为base类,抽象类是不能被实例化的(前面说的static 类也不能被实例化)它必须作为 基类,被别人继承,然后必 ...