Aop

Aop的介绍

什么是Aop

Aop面向切面编程,是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

重点在于切面

应用场景

日志记录,性能统计,安全控制,事务处理,异常处理可将日志记录,异常处理等代码从原程序中抽离出来,

Aop的优点

  1. 提高代码的可重用性
  2. 业务代码编码更简洁
  3. 业务代码维护更高效
  4. 业务功能拓展更便捷

Aop的实际运用

首先我们创建一个java类,里面分别有加,减,乘,除四个方法

@Service
public class Calculate {
//加
public int add(int i,int j){
System.out.println("我是加法");
return i+j;
}
//减
public int sub(int i,int j){
System.out.println("我是减法");
return i-j;
}
//乘
public int mul(int i,int j){
System.out.println("我是乘法");
return i*j;
}
//除
public int div(int i,int j){
System.out.println("我是除法");
return i/j;
}
}

现在有一个需求就是打印每一个方法执行的时间,传统的思维可能就是在每一个方法上打印出时间

public class Calculate {
//加
public int add(int i,int j){
System.out.println("我是加法,执行时间"+ LocalDate.now());
return i+j;
}
//减
public int sub(int i,int j){
System.out.println("我是减法,执行时间"+ LocalDate.now());
return i-j;
}
//乘
public int mul(int i,int j){
System.out.println("我是乘法,执行时间"+ LocalDate.now());
return i*j;
}
//除
public int div(int i,int j){
System.out.println("我是除法,执行时间"+ LocalDate.now());
return i/j;
}

使用AOP来实现

@Aspect
@Component
public class AopConfig {
/**
* @param joinPoint
* @Before:前置通知
* value:切入点表达式 二者加起来构建成为一个切面
* JoinPoint:连接点:可以理解为两个圆形的切点,从这个切点就可以获取到当前执行的目标类及方法
* 前置通知和后置通知的参数的都是 JoinPoint, 前置后置通知都没有返回值
*/
// 表示service包下的所有类所有方法都执行该前置通知
@Before("execution(* com.example.demo.service.*.*(..))")
public void before(JoinPoint joinPoint) {
System.out.println("前置通知开始执行");
System.out.println(joinPoint.getSignature().getName()+"执行时间"+ LocalDate.now());
System.out.println("传入的参数是: " + Arrays.asList(joinPoint.getArgs()));
} //后置通知
@After(value = "execution(* com.example.demo.service.*.*(..))")
public void after(JoinPoint joinPoint) {
System.out.println("后置通知执行");
}
}

执行效如下

前置通知开始执行
add执行时间2022-04-25
正在执行的目标方法是: add
传入的参数是: [1,2]
后置通知执行
前置通知开始执行
div执行时间2022-04-25
正在执行的目标方法是: div
传入的参数是: [1,2]
后置通知执行

注:

这里面的重点就是:execution(* com.example.demo.service..(…))

切入点表达式,值为方法的全名(返回值,包名,方法名,参数)spring容器可根据切入点表达式去找到需要切入的方法,上面这个表达式的意义就是表示service包下的所有类所有方法都执行该前置通知

通知类型

spring容器中共有五种通知类型

  1. 前置通知 @Before 在方法执行前执行
  2. 后置通知 @After 在方法执行后执行
  3. 返回通知 @AfterReturning 在方法执行前执行,无论是否出现异常
  4. 异常通知 @AfterThrowing 在方法执行前执行,出现异常则不执行
  5. 环绕通知 @Around 可以单独完成以上四个通知

环绕通知

 @Around(value = "execution(* com.example.demo.service.*.*(..))")
public int myAround(ProceedingJoinPoint pJoinPoint){
String name = pJoinPoint.getSignature().getName();
Object[] args = pJoinPoint.getArgs();
//args[0]=10; //还可以改传入的参数
int result=0;
try {
System.out.println("执行前置通知"+name+"执行了,传入的参数是"+Arrays.asList(args));
//可以理解为目标方法
result = (int) pJoinPoint.proceed();
System.out.println("返回通知执行了,返回值是"+result); } catch (Throwable e) {
System.out.println("异常通知执行了"+name+"出异常了,异常是"+e);
e.printStackTrace();
}finally {
System.out.println("后置通知执行了"+name+"结束了");
}
//必须要有返回值
return result; }

执行结果如下

执行前置通知add执行了,传入的参数是[1,2]
返回通知执行了,返回值是3
后置通知执行了add结束了

注:如果觉得每次都写切入点表达式很麻烦,可以用以下方法代替,然后在对应的通知注解加上即可

	//与切入点相等  默认为public可以省略
@Pointcut("execution(* com.example.demo.service.*.*(..))")
public void a(){
}
@Before("a()")
public void start(JoinPoint joinPoint){
String name = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println(name+"开始了"+"传入的参数是"+Arrays.asList(args));
}

注意

前置通知和后置通知都可以通过JoinPoint joinPoint来获取目标方法的信息例如:方法名,参数等等

后置通知,在方法执行后执行,所以可以目标方法的信息,返回通知(能获得返回值)和后置通知(不能获得返回值)的区别就是能否获得返回值,

本文章参考自:https://blog.csdn.net/qq_44693065/article/details/124327021

AOP的介绍以及在springboot中的简单使用的更多相关文章

  1. 在商城系统中使用设计模式----简单工厂模式之在springboot中使用简单工厂模式

    1.前言: 不了解简单工厂模式请先移步:在商城中使用简单工厂.在这里主要是对springboot中使用简单工厂模式进行解析. 2.问题: 什么是简单工厂:它的实现方式是由一个工厂类根据传入的参数,动态 ...

  2. 记录一下在SpringBoot中实现简单的登录认证

    代码参考博客: https://blog.csdn.net/weixin_37891479/article/details/79527641 在做学校的课设的时候,发现了安全的问题,就不怀好意的用户有 ...

  3. SpringBoot图文教程5—SpringBoot 中使用Aop

    有天上飞的概念,就要有落地的实现 概念+代码实现是本文的特点,教程将涵盖完整的图文教程,代码案例 文章结尾配套自测面试题,学完技术自我测试更扎实 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例 ...

  4. SpringBoot 中常用注解

    本篇博文将介绍几种SpringBoot 中常用注解 其中,各注解的作用为: @PathVaribale 获取url中的数据 @RequestParam 获取请求参数的值 @GetMapping 组合注 ...

  5. springboot成神之——mybatis在spring-boot中使用的几种方式

    本文介绍mybatis在spring-boot中使用的几种方式 项目结构 依赖 WebConfig DemoApplication 方式一--@Select User DemoApplication ...

  6. springboot中集成memcached

    前言 Memcached 是一个高性能的分布式内存对象缓存系统,其存储性能在某些方面不比redis差,甚至在文本类型数据的存储上性能略优于redis,本文将介绍如何在springboot中集成memc ...

  7. SpringBoot中使用LoadTimeWeaving技术实现AOP功能

    目录 1. 关于LoadTimeWeaving 1.1 LTW与不同的切面织入时机 1.2 JDK实现LTW的原理 1.3 如何在Spring中实现LTW 2. Springboot中使用LTW实现A ...

  8. Springboot中的缓存Cache和CacheManager原理介绍

    背景理解 什么是缓存,为什么要用缓存 程序运行中,在内存保持一定时间不变的数据就是缓存.简单到写一个Map,里面放着一些key,value数据,就已经是个缓存了 所以缓存并不是什么高大上的技术,只是个 ...

  9. Springboot中使用AOP统一处理Web请求日志

    title: Springboot中使用AOP统一处理Web请求日志 date: 2017-04-26 16:30:48 tags: ['Spring Boot','AOP'] categories: ...

  10. 在SpringBoot中配置aop

    前言 aop作为spring的一个强大的功能经常被使用,aop的应用场景有很多,但是实际的应用还是需要根据实际的业务来进行实现.这里就以打印日志作为例子,在SpringBoot中配置aop 已经加入我 ...

随机推荐

  1. 有关js的双向绑定解除方法

    最近碰到了一个bug var persons = [{ number: 1, age: 11, name: "wanghaha", money: -1 }, { number: 2 ...

  2. .NET 环境下的三维渲染库 HelixToolkit.SharpDX

    1. 引言 在 .NET 生态系统中,三维渲染一直是开发者面临的一个挑战.虽然 WPF 提供了基础的 3D 渲染支持,但性能和功能都较为有限.而 HelixToolkit.SharpDX 作为一款基于 ...

  3. Oralcle11.2.0.1.0使用出现的问题

    问题1:oracle中监听程序当前无法识别连接描述符中请求服务 解决方法1: 查看oracle的服务是否开启,计算机->管理->服务和应用程序->服务,如下图 解决方法2: 找到or ...

  4. Ubuntu安装GPU驱动+CUDA+cuDNN的安装方法

    一台有GPU的虚拟机如果没有安装CUDA的驱动,是需要我们手动去进行安装的,介绍Ubuntu操作系统的安装教程. 1. 下载安装文件 NVIDIA CUDA Toolkit Archive 点击上面链 ...

  5. IDA Pro分析dll在exe中的表现

    尝试分析隐式加载和显式加载的dll在exe中进行反汇编时的表现. 1. 测试条件 (1)动态库 testdll1  导出函数 int add(int, int) 和  int add2(int, in ...

  6. Tampermonkey 油猴脚本中文手册(出处:https://www.itblogcn.com/article/2233.html)

    文章目录 @name @namespace @copyright @version @description @icon, @iconURL, @defaulticon @icon64, @icon6 ...

  7. python练习-爬虫(续)

    流程: 1 设置url 2 设置消息头 3 设置消息体 4 获取响应 5 解析相应 6 验证数据 接下来就是查询数据了. # 识别图片中的文字 #image = Image.open('captcha ...

  8. 扫盲ASM

    在进行程序跟踪时,会出现汇编.由于ASM盲,所以添加不少烦恼.有烦恼得想办法解决.对,扫盲ASM. 这里是教材,感觉大白话很好理解(感谢 http://www.ruanyifeng.com/blog/ ...

  9. dify MCP工具调用

    一.概述 前面几篇文章,介绍了Cherry Studio客户端调用MCP,接下来介绍dify如何调用MCP 二.dify插件 需要安装2个插件,分别是:Agent 策略(支持 MCP 工具),MCP ...

  10. python读取文件夹内所有图片名称,随机设置为桌面壁纸且把设置后的图片移到其他文件夹内的方法

    关键词:读取文件夹.读取文件.操作系统.设置壁纸.移动文件 预期实现如下几个步骤 1.获取指定文件夹内所有图片名 2.随机取一张图片设置为壁纸 3.设置为壁纸的图片移动到另外一个文件夹中 第一步,获取 ...