一、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

最新文章

  1. boa + ajax + cgi ajax请求cgi
  2. Android的setVisibility(View.GONE)无效的问题及原因分析(转)
  3. MVC自动绑定整数数组
  4. c语言第11次作业
  5. http 学习 1-1 chapter1-HTTP概述
  6. Java C# .net 和 C C++ 跨平台的区别
  7. CentOS7.x搭建时间同步服务器
  8. Ubuntu16.04 安装ROS及其IDE
  9. nginx worker_processes 配置
  10. 【Vijos】lxhgww的奇思妙想(长链剖分)
  11. centos7破解安装confluence5.9.11
  12. 数据库工具类 JdbcUtils
  13. Nand_ECC_校验和纠错_详解
  14. PHP——自定义比较算法
  15. scratch如何获取透明的图片
  16. IDEA报错:Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled. ('crmWatcherService'错误)
  17. Nuget 下载过慢的解决办法
  18. 糟糕的css用法 1
  19. 游戏服务器学习笔记 4———— master 模块介绍
  20. HiveQL之Database相关操作

热门文章

  1. C++——标准模板库
  2. [转]触发fullgc的条件
  3. nginx启动时指定配置文件
  4. HttpApplication处理管道处理过程简单描述
  5. 理解Login函数
  6. linux 定时任务设置
  7. 简单易用,用Powershell劫持Windows系统快捷键
  8. Django | mysql修改个别表后save()报错
  9. 《深入理解Java虚拟机》读书笔记五
  10. CodeForces -1216B.Shooting