AOP的介绍以及在springboot中的简单使用
Aop
Aop的介绍
什么是Aop
Aop面向切面编程,是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
重点在于切面
应用场景
日志记录,性能统计,安全控制,事务处理,异常处理可将日志记录,异常处理等代码从原程序中抽离出来,
Aop的优点
- 提高代码的可重用性
- 业务代码编码更简洁
- 业务代码维护更高效
- 业务功能拓展更便捷
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容器中共有五种通知类型
- 前置通知 @Before 在方法执行前执行
- 后置通知 @After 在方法执行后执行
- 返回通知 @AfterReturning 在方法执行前执行,无论是否出现异常
- 异常通知 @AfterThrowing 在方法执行前执行,出现异常则不执行
- 环绕通知 @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中的简单使用的更多相关文章
- 在商城系统中使用设计模式----简单工厂模式之在springboot中使用简单工厂模式
1.前言: 不了解简单工厂模式请先移步:在商城中使用简单工厂.在这里主要是对springboot中使用简单工厂模式进行解析. 2.问题: 什么是简单工厂:它的实现方式是由一个工厂类根据传入的参数,动态 ...
- 记录一下在SpringBoot中实现简单的登录认证
代码参考博客: https://blog.csdn.net/weixin_37891479/article/details/79527641 在做学校的课设的时候,发现了安全的问题,就不怀好意的用户有 ...
- SpringBoot图文教程5—SpringBoot 中使用Aop
有天上飞的概念,就要有落地的实现 概念+代码实现是本文的特点,教程将涵盖完整的图文教程,代码案例 文章结尾配套自测面试题,学完技术自我测试更扎实 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例 ...
- SpringBoot 中常用注解
本篇博文将介绍几种SpringBoot 中常用注解 其中,各注解的作用为: @PathVaribale 获取url中的数据 @RequestParam 获取请求参数的值 @GetMapping 组合注 ...
- springboot成神之——mybatis在spring-boot中使用的几种方式
本文介绍mybatis在spring-boot中使用的几种方式 项目结构 依赖 WebConfig DemoApplication 方式一--@Select User DemoApplication ...
- springboot中集成memcached
前言 Memcached 是一个高性能的分布式内存对象缓存系统,其存储性能在某些方面不比redis差,甚至在文本类型数据的存储上性能略优于redis,本文将介绍如何在springboot中集成memc ...
- SpringBoot中使用LoadTimeWeaving技术实现AOP功能
目录 1. 关于LoadTimeWeaving 1.1 LTW与不同的切面织入时机 1.2 JDK实现LTW的原理 1.3 如何在Spring中实现LTW 2. Springboot中使用LTW实现A ...
- Springboot中的缓存Cache和CacheManager原理介绍
背景理解 什么是缓存,为什么要用缓存 程序运行中,在内存保持一定时间不变的数据就是缓存.简单到写一个Map,里面放着一些key,value数据,就已经是个缓存了 所以缓存并不是什么高大上的技术,只是个 ...
- Springboot中使用AOP统一处理Web请求日志
title: Springboot中使用AOP统一处理Web请求日志 date: 2017-04-26 16:30:48 tags: ['Spring Boot','AOP'] categories: ...
- 在SpringBoot中配置aop
前言 aop作为spring的一个强大的功能经常被使用,aop的应用场景有很多,但是实际的应用还是需要根据实际的业务来进行实现.这里就以打印日志作为例子,在SpringBoot中配置aop 已经加入我 ...
随机推荐
- 有关js的双向绑定解除方法
最近碰到了一个bug var persons = [{ number: 1, age: 11, name: "wanghaha", money: -1 }, { number: 2 ...
- .NET 环境下的三维渲染库 HelixToolkit.SharpDX
1. 引言 在 .NET 生态系统中,三维渲染一直是开发者面临的一个挑战.虽然 WPF 提供了基础的 3D 渲染支持,但性能和功能都较为有限.而 HelixToolkit.SharpDX 作为一款基于 ...
- Oralcle11.2.0.1.0使用出现的问题
问题1:oracle中监听程序当前无法识别连接描述符中请求服务 解决方法1: 查看oracle的服务是否开启,计算机->管理->服务和应用程序->服务,如下图 解决方法2: 找到or ...
- Ubuntu安装GPU驱动+CUDA+cuDNN的安装方法
一台有GPU的虚拟机如果没有安装CUDA的驱动,是需要我们手动去进行安装的,介绍Ubuntu操作系统的安装教程. 1. 下载安装文件 NVIDIA CUDA Toolkit Archive 点击上面链 ...
- IDA Pro分析dll在exe中的表现
尝试分析隐式加载和显式加载的dll在exe中进行反汇编时的表现. 1. 测试条件 (1)动态库 testdll1 导出函数 int add(int, int) 和 int add2(int, in ...
- Tampermonkey 油猴脚本中文手册(出处:https://www.itblogcn.com/article/2233.html)
文章目录 @name @namespace @copyright @version @description @icon, @iconURL, @defaulticon @icon64, @icon6 ...
- python练习-爬虫(续)
流程: 1 设置url 2 设置消息头 3 设置消息体 4 获取响应 5 解析相应 6 验证数据 接下来就是查询数据了. # 识别图片中的文字 #image = Image.open('captcha ...
- 扫盲ASM
在进行程序跟踪时,会出现汇编.由于ASM盲,所以添加不少烦恼.有烦恼得想办法解决.对,扫盲ASM. 这里是教材,感觉大白话很好理解(感谢 http://www.ruanyifeng.com/blog/ ...
- dify MCP工具调用
一.概述 前面几篇文章,介绍了Cherry Studio客户端调用MCP,接下来介绍dify如何调用MCP 二.dify插件 需要安装2个插件,分别是:Agent 策略(支持 MCP 工具),MCP ...
- python读取文件夹内所有图片名称,随机设置为桌面壁纸且把设置后的图片移到其他文件夹内的方法
关键词:读取文件夹.读取文件.操作系统.设置壁纸.移动文件 预期实现如下几个步骤 1.获取指定文件夹内所有图片名 2.随机取一张图片设置为壁纸 3.设置为壁纸的图片移动到另外一个文件夹中 第一步,获取 ...