一、Spring的AOP分为以下5种类型通知

①前置通知(Before):在连接点执行前执行该通知

②正常返回通知(AfterReturning):在连接点正常执行完后执行该通知,若目标方法执行异常则不会执行该通知

③异常返回通知(AfterThrowing):在连接点执行抛出异常时执行该通知

④后置通知(after/finally):在连接点执行完成后(不管成功、失败、异常)都会执行该通知

⑤环绕通知(Around):围绕在连接点前后

二、执行顺序

1、正常执行

①环绕通知:@Around

②前置通知:@Before

③连接点方法执行

④环绕通知:@Around

⑤后置通知:@After

⑥正常返回通知:@AfterReturning

  其他结论说出来也没意思,还是自己通过简单demo测试一下就出来了

三、测试

1、自定义注解

2、切面

@Aspect
@Component
@Slf4j
public class LogAspect {
//切点范围
@Pointcut("@annotation(com.test.annotation.OperateLog)")
public void operateMethod(){}
//前置通知
@Before("operateMethod()")
public void before(){
log.info("前置通知:Before");
}
//正常返回通知
@AfterReturning("operateMethod()")
public void afterReturning(){
log.info("后置通知:AfterReturning");
}
//后置通知
@After("operateMethod()")
public void after(){
log.info("后置通知:After");
}
//异常返回通知
@AfterThrowing("operateMethod()")
public void afterThrowing(){
log.info("异常返回通知:AfterThrowing");
}
//环绕通知
@Around("operateMethod()")
public Object methodAround(ProceedingJoinPoint joinPoint) throws Throwable{
log.info("环绕通知:around------前");
Object result=null;
OperateLog annotation = getAnnotation(joinPoint);
try {
result=joinPoint.proceed();
} catch (Throwable throwable) {
log.info("环绕通知:around------异常");
}
try {
String system = annotation.system();
int flag = annotation.flag();
String operatorName = annotation.operatorName();
log.info("切面校验信息,系统:【{}】,标识:【{}】,操作员名称:【{}】", system,flag,operatorName);
//日志入库业务
} catch (Exception e) {
log.info("切面异常",e);
}
log.info("环绕通知:around------后");
return result;
} private OperateLog getAnnotation(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Method method = signature.getMethod();
return method.getAnnotation(OperateLog.class);
}
}

切面代码

3、定义service接口并实现

service接口

 实现类

4、测试controller

@RestController
@Slf4j
public class LogController {
@Autowired
private IHelloService helloService; @RequestMapping("/test")
@OperateLog(system = "系统1",flag = 1,operatorName = "操作员1")
public void test() throws Exception {
OperateLog test = (OperateLog)AnnotationUtil.getAnnotation(LogController.class, OperateLog.class, "test", 1);
log.info("更改前的注解属性:【{}】,【{}】,【{}】",test.flag(),test.operatorName(),test.system() );
//更改注解OperateLog的system属性值为“系统2”
AnnotationUtil.ModifyAnnotation(LogController.class, OperateLog.class, "test", "system", "系统2");
//更改flag的属性值为2
AnnotationUtil.ModifyAnnotation(LogController.class, OperateLog.class, "test", "flag", 2);
//更改注解的operatorName属性值为:张三
AnnotationUtil.ModifyAnnotation(LogController.class, OperateLog.class, "test", "operatorName", "张三");
log.info("更改后的注解属性:【{}】,【{}】,【{}】",test.flag(),test.operatorName(),test.system() );
}
@RequestMapping("/test1")
@OperateLog(system = "系统1",flag = 1,operatorName = "操作员1")
public void test1() throws Exception {
helloService.IsayHello();
}
@RequestMapping("/test2")
@OperateLog(system = "系统1",flag = 1,operatorName = "操作员1")
public void test2() throws Exception {
helloService.say("我是controller");
}
@RequestMapping("/test3")
@OperateLog(system = "系统1",flag = 1,operatorName = "操作员1")
public void test3() throws Exception {
helloService.error(true);
}
@RequestMapping("/test4")
@OperateLog(system = "系统1",flag = 1,operatorName = "操作员1")
public void test4() throws Exception {
helloService.error(false);
}
}

controller

5、测试

三、总结

1、Aop可以理解为一个同心圆,要执行的目标方法(底层还是jdk或cglib动态代理)为圆心,最外层的order最小,环绕、前置通知先执行,后置、正常返回通知后执行

2、多个aop执行的执行顺序可以使用@Order注解来实现

本项目地址https://github.com/Simple-Coder/aop-demo

SpringAOP学习之5种通知的更多相关文章

  1. SpringAOP之使用切入点创建通知

    之前已经说过了SpringAOP中的几种通知类型以及如何创建简单的通知见地址 一.什么是切入点 通过之前的例子中,我们可以创建ProxyFactory的方式来创建通知,然后获取目标类中的方法.通过不同 ...

  2. SpringAOP使用注解实现5种通知类型

    spring aop的5种通知类型都有 Before前置通知 AfterReturning后置通知 Around环绕通知 AfterThrowing异常通知 After最终通知 首先创建接口和实现类 ...

  3. Java开发学习(十六)----AOP切入点表达式及五种通知类型解析

    一.AOP切入点表达式 对于AOP中切入点表达式,总共有三个大的方面,分别是语法格式.通配符和书写技巧. 1.1 语法格式 首先我们先要明确两个概念: 切入点:要进行增强的方法 切入点表达式:要进行增 ...

  4. spring-aop学习

     SpringAOP学习 author:luojie 1.  AOP中的基本概念 AOP的通用术语,并非spring java所特有.很遗憾AOP的术语不是特别的直观.但如果让Spring java来 ...

  5. spring aop 的五种通知类型

    本文转自:http://blog.csdn.net/cqabl/article/details/46965197 spring aop通知(advice)分成五类: 前置通知[Before advic ...

  6. spring aop的五种通知类型

    昨天在腾讯课堂看springboot的视频,老师随口提问,尼玛竟然回答错了.特此记录! 问题: Spring web项目如果程序启动时出现异常,调用的是aop中哪类通知? 正确答案是: 异常返回通知. ...

  7. WebGL three.js学习笔记 6种类型的纹理介绍及应用

    WebGL three.js学习笔记 6种类型的纹理介绍及应用 本文所使用到的demo演示: 高光贴图Demo演示 反光效果Demo演示(因为是加载的模型,所以速度会慢) (一)普通纹理 计算机图形学 ...

  8. Spring-AOP的五种通知和切面的优先级、通知变量声明

    SpringAOP的通知分为以下五种: 1前置通知(@before)在连接点执行之前执行的代码 2后置通知(@after)在连接点执行之后执行的代码,不管连接点执行后是否出现异常,后置通知都会执行,但 ...

  9. Spring4.0学习笔记(11) —— Spring AspectJ 的五种通知

    Spring AspectJ 一.基于注解的方式配置通知 1.额外引入的jar包: a) com.springsource.org.aopalliance-1.0.0.jar b) com.sprin ...

随机推荐

  1. linux分区命令parted的用法

    parted的适用场景 创建操作大于2T的分区 一般情况下,我们都是选择使用fdisk工具来进行分区,但是目前在实际生产环境中使用的磁盘空间越来越大,呈TiB级别增长:而常用的fdisk这个工具对分区 ...

  2. AntDesign(React)学习-14 使用UMI提供的antd模板

    1.UMI提供了可视化antd模板,可以直接添加到项目中修改用 比如将个人中心添加到项目中 2.选择个人中心,确定 3.成功 4.打开项目 5.Route文件也自动添加 根路由有exact:true后 ...

  3. C语言--“.”与“->”有什么区别?

    这虽然是个小问题,但有时候很容易让人迷惑,因为有的时候用混淆了,程序编译不通过.   下面说说我对它们的理解.   一般情况下用“.”,只需要声明一个结构体.格式是,结构体类型名+结构体名.然后用结构 ...

  4. 高端OLED电视成行业突破口,苏宁助力显示技术市场迭代

    编辑 | 于斌 出品 | 于见(mpyujian) 在电商与线上渠道越来越占据举足轻重地位的年代,电商平台巨头们越来越有底气喊出"推动行业技术升级"的口号.的确,再好的技术升级也需 ...

  5. U盘拷贝目标文件过大无法复制时的解决方法

    在cmd下输入:convert U盘符:/fs:ntfs    --->  回车 转换完成后可以看到U盘属性为NTFS了 这时就可以复制大文件到U盘了

  6. Rider代码格式设置

    单选注释格式设置: File/Settings(Ctrl+Alt+S/Command+Option+S)/Code Style/C#选择Other

  7. 记一次和“N+1”的擦肩而过

    这周五,就是昨天,部门走了3个人.他们是"被离职"的,从被通知到走人,只过了一周左右.一开始经理和他们谈的时候,说有没有赔偿不能确定,然后到周四左右,上面的人可能是等急了,才说年终 ...

  8. 什么是类的hashcode值

    1.要知道什么是类的hashcode值,首要要了解什么是hash(哈希).Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换 ...

  9. dijkstra堆优化板子

    咕咕咕. #include<queue> #include<cstdio> #include<cstring> #include<algorithm> ...

  10. AcWing 827. 双链表

    https://www.acwing.com/problem/content/829/ #include <iostream> using namespace std; ; int m; ...