SpringBoot实践(三十九):如何使用AOP

news/2024/12/2 20:52:38/

目录

直接使用@Aspect

定义切面逻辑

模拟业务代码

测试输出

 自定义注解方式

自定义切面注解

定义切入点逻辑

模拟业务代码

测试输出


面向切面(AOP) 是spring重要特性,在功能上切面编程是面向对象编程的很好的补充,面向对象强调封装和开闭原则,如果多个对象有通用行为和方法,将造成很多冗余代码,AOP将通用功能作为切面插入到业务逻辑中(如通用的日志打印,异常处理,license判断等)抽取通用逻辑,减少代码冗余,并且无侵入地修改代码,在实现层面上都是通过动态代理实现,默认cglib方式,SpringBoot简化了它的使用,常用的2种方式:直接使用aspect注解扫描或基于自定义的注解。

首先在springBoot的依赖管理基础上,引入aop的依赖:

		<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>

直接使用@Aspect

定义切面逻辑

使用@Aspect实现一个通用的业务逻辑,比如日志打印,提供了几种切面增强方式:前置增强@Before,后置增强@After,环绕返回@AfterReturning,环绕增强@Around(前后都有),异常抛出增强AfterThrowing,执行顺序是:

  1. 正常情况:@Around-->@Before-->目标方法执行-->@AfterReturning-->@After-->@AfterReturning-->@Around
  2. 异常情况:@Around-->@Before-->目标方法执行-->@AfterThrowing-->@After-->AfterThrowing-->@Around

 如下:

@Component
@Aspect
@Slf4j
public class LoggingAspect {@Pointcut("execution(public * com.example.hello.controller.*.*())")public void LogAspect(){}@Before("LogAspect()")public void doBefore(JoinPoint joinPoint){log.info(" -------------------------> this is before.");}@After("LogAspect()")public void doAfter(JoinPoint joinPoint){log.info(" -------------------------> this is after.");}@AfterReturning("LogAspect()")public void doAfterReturning(JoinPoint joinPoint){log.info(" -------------------------> this is afterReturning.");}@AfterThrowing("LogAspect()")public void deAfterThrowing(JoinPoint joinPoint){log.info(" -------------------------> this is deAfterThrowing.");}@Around("LogAspect()")public Object deAround(ProceedingJoinPoint joinPoint) throws Throwable{log.info(" -------------------------> this is deAround.");return joinPoint.proceed();}
}

模拟业务代码

这里的切入点是controller类中方法,controller的方法定义如下,其中helloService模拟的是真实的业务代码,这个controller不需要做任何修改,测试正常输入和异常输出;

    @GetMapping("/hello")public String sayHello(){log.info("---- 模拟基于标准注解的切面过程 ---------- >running hello");return helloService.sayHello();}@GetMapping("/hello2")@LogAnnotation(param = "HelloController")public String sayHello2(){log.info("---- 模拟异常后切面过程 ---------- >running hello2");throw new RuntimeException();}

测试输出

 在正常输出业务代码的前后,及方法的全局都被注入了自定义的逻辑: 

异常输出:

 自定义注解方式

上面的方式可以无侵入地为我们的业务代码增加某些通用逻辑,同时我们也可以自定义注解方式,然后将自定义注解增加到部分业务代码中;

自定义切面注解

定义注解LogAannotation,能够在方法和类上标注,有个参数param默认空;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface LogAnnotation {String param() default "";
}

定义切入点逻辑

LoggingAspect2实现了切入点和自定义注解@LogAnnotation的逻辑,在切入点前后执行时间打印;

@Aspect
@Component
@Slf4j
public class LoggingAspect2 {@Around("@annotation(logAnnotation)")public Object around(ProceedingJoinPoint joinPoint, LogAnnotation logAnnotation) throws Throwable {log.info(String.format("time now :%s",new Date()));Object o = joinPoint.proceed();log.info(String.format("time now :%s",new Date()));return o;}
}

模拟业务代码

这种方式需要修改业务代码,增加对于自定义注解的传参;

    @GetMapping("/hello3")@LogAnnotation(param = "HelloController")public String sayHello3(){log.info("---- 模拟基于自定义注解的切面 ---------- >running hello3");return helloService.sayHello();}

测试输出

这里因为上面的@aspect注解增加了环绕增强,因此hello3的上下日期打印是自定义注解的实现。


http://www.ppmy.cn/news/11881.html

相关文章

04_FreeRTOS任务挂起和恢复函数

目录 任务的挂起与恢复的API函数 任务挂起函数介绍 任务恢复函数介绍 中断中恢复函数 vTaskSuspend()任务挂起函数 vTaskResume()任务中恢复函数 xTaskResumeFromISR()中断中恢复函数 任务的挂起与恢复的API函数 挂起:挂起任务类似暂停,可恢复;删除任务,无法恢复,类似“…

敏捷是知与行的功夫

敏捷不是“一”种方法 “敏捷是一种用于项目管理和软件开发的迭代方法&#xff0c;可帮助团队更快地向客户交付价值并减少风险。 它不是将一切都押在“大爆炸”发布上&#xff0c;而是以小的增量交付成果。 不断评估需求、计划和结果&#xff0c;因此能够快速地响应变化。” 以…

大数据必学Java基础(一百二十):Maven工程的介绍与创建

文章目录 Maven工程的介绍与创建 一、Maven工程类型 1、POM工程 2、JAR工程 3、WAR工程

【自定义类型】-结构体,枚举,联合

&#x1f387;作者&#xff1a;小树苗渴望变成参天大树 &#x1f496;作者宣言&#xff1a;认真写好每一篇博客 &#x1f9e8;作者gitee:link 如 果 你 喜 欢 作 者 的 文 章 &#xff0c;就 给 作 者 点 点 关 注 吧&#xff01; &#x1f38a;自定义类型&#x1f389;前言&a…

OOM 机制

OOM 机制 “我们从OOM的角度来帮大家提高一点内存方面的知识&#xff0c;虽然不能说帮助人们来完全解决内存问题&#xff0c;但是也能从一个侧面来提高大家分析内存问题相关的能力。” 这是关于 Linux 内核的学习笔记&#xff0c;重点要了解 OOM 这块的相关知识点。 1 相关概念…

【正点原子FPGA连载】 第十七章 呼吸灯实验 摘自【正点原子】DFZU2EG/4EV MPSoC 之FPGA开发指南V1.0

1&#xff09;实验平台&#xff1a;正点原子MPSoC开发板 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id692450874670 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html 第十七章 呼吸灯…

【2022年度总结】总结过去,展望未来

文章目录前言回顾过去一、刷题道路两眼黑二、助人为乐本身便是一种快乐展望未来兔年Flag博客文章竞赛目标学习目标志同道合前言 注册CSDN一年了&#xff0c;新年伊始&#xff0c;正好趁着这个时间复盘一下逝去的2022&#xff01; 很幸运&#xff0c;在对计算机知识懵懂无知的时…

awk练习

1、获取根分区剩余大小 [rootlocalhost test]# df -Th / | awk NR2 {print $5} 16G2、获取当前机器ip地址 [rootlocalhost test]# hostname -I 192.168.6.20 3、统计出apache的access.log中访问量最多的5个IP [rootlocalhost test]# awk {ip[$1]} END {for (a in ip) print …