springboot实现Aop

ops/2024/10/10 20:52:49/

一、原理

AOP(Aspect Oriented Programming)的意思是:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。利用AOP可对业务逻辑进行增强,在不改变原有逻辑的基础上,在其前后进行处理。降低了耦合性,减少了大量冗余的操作。特别适合用于大量方法都需要进行相同处理的操作。

二、概念

aop可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加某种特定功能的一种技术。

这么看上去我们的程序就像个洋葱一样是一瓣一瓣的,我们的业务代码在中间,aop实现的增强方法会在我们打的业务方法执行前或者是执行后执行。

我们需要了解的:

1、切面(Aspect):一般是指被@Aspect修饰的类,代表着某一具体功能的AOP逻辑。
2、切入点(Pointcut):选择对哪些方法进行增强。
3、通知(Advice):对目标方法的增强,有一下五种增强的类型。
4、环绕通知(@Around):内部执行方法,可自定义在方法执行的前后操作。
5、前置通知(@Before):在方法执行前执行。
6、后置通知(@After):在方法执行后执行。
7、返回通知(@AfterReturning):在方法返回后执行。
8、异常通知(@AfterThrowing):在方法抛出异常后执行。
9、连接点(JoinPoint):就是那些被切入点选中的方法。这些方法会被增强处理。

对于不同的方法,使其生效的匹配方式也有很多:

表达式类型  

 功能
execution() 匹配方法,最全的一个
args()  匹配入参类型
@args()匹配入参类型上的注解
@annotation() 匹配方法上的注解
within()匹配类路径
@within() 匹配类上的注解
this()匹配类路径,实际上AOP代理的类
target()匹配类路径,目标类
@target()匹配类上的注解

三、实现

在这里我们使用annotation注解的方式实现切入

1、添加依赖

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

2、创建一个用于切入的注解

ElementType.TYPE   声明这个注解可以在类上使用

ElementType.METHOD  声明这个注解可以在方法上使用

java">@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Aop {
}

3、编写切面类

a.通过@Aspect告诉spring容器这是一个切面类,同时使用@Component注解将其声明成spring容器的组件

b.创建一个成员方法(不用有具体的实现),在上面添加上@Pointcat注解,声明这是个切入点方法,在这里我们就可以选择不同的匹配方式,我们这里使用的是@Aop注解的方式

c.实现具体的增强方法,通过@After、@Before...,并且在其中引入切入点方法

java">
@Aspect
@Component
public class ScheduledAop {@Pointcut("@annotation(com.zxc.scheduled.annotation.Aop)")public void authcat(){}@After("authcat()")public void print(JoinPoint joinPoint){System.out.println("catprint running");}@Before("authcat()")public void before(JoinPoint joinPoint){String name = joinPoint.getSignature().getName();System.out.println(name);}@Around("authcat()")public void around(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("开始执行");Object proceed = joinPoint.proceed();System.out.println("执行结束");}@AfterThrowing(value = "authcat()",throwing = "e")public void execption(JoinPoint joinPoint,Exception e){System.out.println(joinPoint.getSignature().getName() + ".exception:" + e.getMessage());}@AfterReturning("authcat()")public void afterReturn(JoinPoint joinPoint){System.out.println(joinPoint.getSignature().getName() + "执行结束");}
}

4、使用aop

在具体的业务方法上添加上我们自定义的@Aop注解,告诉aop从这里切入,这里我们自己抛出了个异常,用来测试@AfterException,异常的前置通知

java">@Component
public class MySchduled {private int count = 0;@Aop@Scheduled(cron = "0/3 * * * * ? ")public void print(){System.out.println("hello:" + count++);if(count == 3){throw new RuntimeException("hello");}}
}

5、开启aop

我们需要在启动类或者配置类上添加@EnableAspectJAutoProxy,开启aop

java">@SpringBootApplication
@EnableAspectJAutoProxy
public class AuthApplication {public static void main(String[] args) {SpringApplication.run(AuthApplication.class,args);}
}

四、aop的应用场景

  • 记录日志。通过在方法调用前后插入切面逻辑,可以方便地实现日志记录功能,例如在方法调用前记录方法名和参数,以及在方法调用后记录方法的返回值。
  • 监控方法运行时间(监控性能)。AOP可以用于监控方法的运行时间,从而找出性能瓶颈,提高系统的性能。
  • 权限控制。通过在方法调用前插入切面逻辑,可以实现安全性检查功能,例如检查用户的权限,只允许有特定权限的用户访问某些方法。
  • 缓存优化。AOP可以用于实现缓存管理功能,例如在方法调用前检查缓存中是否存在结果,在方法调用后将结果存入缓存,以提高系统的性能,避免重复计算。
  • 事务管理。AOP可以用于实现事务管理功能,例如在方法调用前开启事务,在方法调用后提交事务或回滚事务,简化事务管理的代码,提高代码的可读性和可维护性。
  • 异常处理。AOP可以用于实现异常处理功能,例如在方法调用后捕获异常并进行处理,统一处理异常,避免在每个方法中都进行异常处理的重复代码。
  • 性能统计和计数。AOP可以用于统计方法的执行时间、调用次数等信息,帮助定位系统瓶颈和优化点。

http://www.ppmy.cn/ops/39154.html

相关文章

ESP32引脚入门指南(五):从理论到实践(SPI)

ESP32 微控制器因其丰富的外设接口而备受赞誉&#xff0c;其中SPI&#xff08;Serial Peripheral Interface&#xff09;是一种常见的通信协议。本文将深入探讨ESP32的SPI、HSPI&#xff08;High-Speed SPI&#xff09;和VSPI&#xff08;Very High-Speed SPI&#xff09;接口&…

【JavaEE网络】用Form与Ajax构建HTTP请求

目录 通过 form 表单构造 HTTP 请求form 发送 GET 请求form 发送 POST 请求 通过 ajax 构造 HTTP 请求发送 GET 请求发送 POST 请求发送 application/json 数据封装 ajax 方法 通过 form 表单构造 HTTP 请求 form (表单) 是 HTML 中的一个常用标签. 可以用于给服务器发送 GET …

20_Scala集合_不可变数组Array

文章目录 Array1.创建不可变数组Array1.1直接new1.2apply方法 2.Array改查3.mkString()4.不可变数组Array遍历for循环遍历foreach遍历foreach匿名写法 Appendix Array –Array不可变数组&#xff0c;增删数据不会使源数组发生变化&#xff0c;而是会产生新数据 –scala中数组…

2024 年最新使用 ntwork 框架搭建企业微信机器人详细教程

NTWORK 概述 基于 PC 企业微信的 api 接口&#xff0c;支持收发文本、群、名片、图片、文件、视频、链接卡片等。 下载安装 ntwork pip install ntwork国内源安装 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple ntwork企业微信版本下载 官方下载&#xff1a;h…

JCR一区 | Matlab实现1D-2D-GASF-CNN-GRU-MATT的多通道输入数据分类预测

JCR一区 | Matlab实现1D-2D-GASF-CNN-GRU-MATT的多通道输入数据分类预测 目录 JCR一区 | Matlab实现1D-2D-GASF-CNN-GRU-MATT的多通道输入数据分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 基本介绍 Matlab实现1D-2D-GASF-CNN-GRU-MATT的多通道输入数据分类预…

c++ 线程实验

在C中&#xff0c;你可以使用C11或更高版本的线程库来创建和管理线程。以下是一个简单的C线程实验示例&#xff0c;该示例展示了如何创建和启动一个线程&#xff0c;以及如何在主线程和子线程中执行不同的任务。 #include <iostream> #include <thread> #include …

hyper-v启动centos7虚拟机不能联网

虚拟网卡要和之前虚拟机里面设置的GATEWAY一致。 安装CentOS遇到Error setting up base repository换url 或者换镜像包iso(这个有用&#xff09; 没掌握摸Yu的精髓 好累啊

Python写了for i in range(10)却只打印一遍?

题目&#xff1a;定义一个两个参数的重复打印函数&#xff0c;第一个参数指定要打印的字符串&#xff0c;第二个参数指定要重复打印的次数&#xff0c;在主程序中调用该函数&#xff0c;打印10遍你的学号姓名。 为什么调用函数后结果只打印了一遍? 看了题目感觉就很诡异&#…