【Spring】Spring中AOP的简介和基本使用,SpringBoot使用AOP

news2024/10/7 4:32:30

  📝个人主页:哈__

期待您的关注 

目录

一、AOP简介

二、AOP个人浅谈

三、AOP中几个核心的方法注解

四、AOP中几个核心的属性

1.切入点(PointCut)

五、代码演示

1.SpringBoot引入依赖

2.定义一个AOP,也就是切面类 

3.使用自定义注解进行增强

六、AOP实现的原理


一、AOP简介

 AOP的全称是Aspect-Oriented Programming,即面向切面编程(也称面向方面编程)。它是面向对象编程(OOP)的一种补充,目前已成为一种比较成熟的编程方式。

在传统的业务处理代码中,通常都会进行事务处理、日志记录等操作。虽然使用OOP可以通过组合或者继承的方式来达到代码的重用,但如果要实现某个功能(如日志记录),同样的代码仍然会分散到各个方法中。这样,如果想要关闭某个功能,或者对其进行修改,就必须要修改所有的相关方法。这不但增加了开发人员的工作量,而且提高了代码的出错率。

为了解决这一问题,AOP思想随之产生。AOP采取横向抽取机制,将分散在各个方法中的重复代码提取出来,然后在程序编译或运行时,再将这些提取出来的代码应用到需要执行的地方。这种采用横向抽取机制的方式,采用传统的OOP思想显然是无法办到的,因为OOP只能实现父子关系的纵向的重用。虽然AOP是一种新的编程思想,但却不是OOP的替代品,它只是OOP的延伸和补充。

 可以看看类和切面的关系,图片来自黑马程序员。

 行了,到了这一步了也不就在废话了,我在尽量不使用太多专业术语的情况下尽可能给大家讲明白AOP。

二、AOP个人浅谈

在我们传统的OOP(面向对象编程)时,在我们原有的方法上我们希望做一些修改,我们希望啊,在执行这个方法之前通知我们的老板,告诉他我已经开始执行任务啦,不要再催促我了。在方法执行结束后,我还要把执行结果告诉老板。那么你会怎么做,是如下边的代码一样吗?

这样子做的确没问题,但是你有没有想过,如果我们的老板比较认真,每一项任务都要向老板汇报,那么你这样写代码还方便吗?如果你只有几项任务的话还好说,就是累一些,但如果你有五十项,一百项呢?

这时AOP就凸显出它的优点了。如果看了简介不明白什么是AOP,那么现在来看看我的理解。

你有很多的任务,你无法把每一项任务都向老板汇报。这时有着这样的一个组织,这个组织可以帮你和老板进行沟通,如果你想对你任务进行这样的能力增强,你就要告诉这个组织,你需要他们的帮助。什么意思呢?我用一张图来解释。

 你需要AOP给你提供的帮助,你就需要向AOP提供你要进行业务能力增强的方法的路径,AOP找到这个方法就会对方法进行增强,在你调用方法的时候就会进行增强。

这下你总能理解什么是AOP了吧。

三、AOP中几个核心的方法注解

下边的代码我只使用的Around,其他的注解大家可以看看其他文章,或者自己试一下。

四、AOP中几个核心的属性

1.切入点(PointCut)

切入点就是用来描述我们到底要对哪个方法进行增强的,我们需要提供一串切入点需要的表达式。

切入点表达式的规则如下。

execution(modifier? ret-type declaring-type?name-pattern(param-pattern) throws-pattern?)
  • modifier:匹配修饰符,public, private 等,省略时匹配任意修饰符
  • ret-type:匹配返回类型,使用 * 匹配任意类型
  • declaring-type:匹配目标类,省略时匹配任意类型
    • .. 匹配任意的包及其子包
  • name-pattern:匹配方法名称,使用 * 表示通配符
    • * 表示所有的方法
    • set* 匹配名称以 set 开头的方法
  • param-pattern:匹配参数类型和数量
    • () 匹配没有参数的方法
    • (..) 匹配有任意数量参数的方法
    • (*) 匹配有一个任意类型参数的方法
    • (*,int) 匹配有两个参数的方法,并且第一个为任意类型,第二个为 int 类型
  • throws-pattern:匹配抛出异常类型,省略时匹配任意类型

 下边的PointCut注解就传入了一个切入点表达式。

@Pointcut(value = "execution(* com.example.shardingsphere.controller.*.*(..))")

五、代码演示

1.SpringBoot引入依赖

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

2.定义一个AOP,也就是切面类 

@Component
@Aspect
public class GlobalAspect {
    @Pointcut(value = "execution(* com.example.shardingsphere.controller.*.*(..))")
    public void pointCut(){}

    @Around(value =  "pointCut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object proceed = null;
        System.out.println("通知老板开始统计了");
        proceed = proceedingJoinPoint.proceed();
        System.out.println("告诉老板统计结果");
        return proceed;
    }
}

 ProceedingJointPoint类还有许多的方法可以使用,比如获取原来方法的参数等功能。以下内容来自转载。

public interface JoinPoint {  
   String toString();         //连接点所在位置的相关信息  
   String toShortString();    //连接点所在位置的简短相关信息  
   String toLongString();     //连接点所在位置的全部相关信息  
   Object getThis();          //返回AOP代理对象,也就是com.sun.proxy.$Proxy18
   Object getTarget();        //返回目标对象,一般我们都需要它或者(也就是定义方法的接口或类,为什么会是接口呢?
                              //这主要是在目标对象本身是动态代理的情况下,例如Mapper。所以返回的是定义方法的对象如
                              //aoptest.daoimpl.GoodDaoImpl或com.b.base.BaseMapper<T, E, PK>)
   Object[] getArgs();        //返回被通知方法参数列表  
   Signature getSignature();  //返回当前连接点签名。其getName()方法返回方法的FQN,如void aoptest.dao.GoodDao.delete()
                              //或com.b.base.BaseMapper.insert(T)(需要注意的是,很多时候我们定义了子类继承父类的时候,
                              //我们希望拿到基于子类的FQN,无法直接拿到,要依赖于
                              //AopUtils.getTargetClass(point.getTarget())获取原始代理对象,下面会详细讲解)
   SourceLocation getSourceLocation();//返回连接点方法所在类文件中的位置  
   String getKind();           //连接点类型  
   StaticPart getStaticPart(); //返回连接点静态部分  
  }  

————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,
                        
原文链接:https://blog.csdn.net/feiying0canglang/article/details/120711774

同时在启动程序上加上注解。

@EnableAspectJAutoProxy

进行测试,我写了这样的一个方法。

@GetMapping("/test2")
    public String test(){
        System.out.println("开始统计公司工资情况");
        return "执行完毕";
    }

结果如下图所示。 

你能够看到,AOP已经成功的增强了我们原来的业务逻辑,这说明我们之后再也不用在我们的业务逻辑中进行这样的统计了,我们可以直接在切面类中进行功能的增强,并且切面类的代码可以复用,提高我们的开发效率。

3.使用自定义注解进行增强

每次想要增强一个方法我们就得写一个表达式,如果是有通配符的话还好说,但如果我们使用了通配符,那就说明可能对所有的方法进行增强,但有一些方法我不想进行增强,这可怎么办?没关系,我们可以使用自定义的注解来实现。

我们的表达式不在指向方法了,我们指向注解,哪个方法加了这个注解,哪个方法就需要增强。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAspect {
}

修改表达式。也就是我们在哪里定义的这个注解。

@Pointcut(value = "@annotation(com.example.shardingsphere.aop.MyAspect))")

之后在我们的controller中的test方法上加上@MyAspect注解。进行测试。结果是一样的。

六、AOP实现的原理

这里就简单的说一下,AOP是通过Jdk动态代理或者Cglib动态代理实现的,我们调用我们需要增强的方法,实际上是调用了代理类的方法,由代理类真正的执行我们的业务逻辑。想了解jdk动态代理可以看看我的这篇博客【Java】jdk1.8 Java代理模式,Jdk动态代理讲解(非常详细,附带class文件)-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1640045.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据库主从架构】

【数据库主从架构】 1. 什么是数据库的主从架构1.1 主从复制1.1.1 MySQL的主从主从复制技术三级目录 1. 什么是数据库的主从架构 随着公司业务线的增多&#xff0c;各种数据都在迅速增加&#xff0c;并且数据的读取流量也大大增加&#xff0c;就面临着数据安全问题&#xff0c;…

ICode国际青少年编程竞赛- Python-1级训练场-基础训练1

ICode国际青少年编程竞赛- Python-1级训练场-基础训练1 1、 Dev.step(4)2、 Dev.step(-4) Dev.step(8)3、 Dev.turnLeft() Dev.step(4)4、 Dev.step(3) Dev.turnLeft() Dev.step(-1) Dev.step(4)5、 Dev.step(-1) Dev.step(3) Dev.step(-2) Dev.turnLeft() Dev.step(…

Servlet(一些实战小示例)

文章目录 一、实操注意点1.1 代码修改重启问题1.2 Smart Tomcat的日志1.3 如何处理错误 一. 抓自己的包二、构造一个重定向的响应&#xff0c;让页面重定向到百度主页三、让服务器返回一个html数据四、表白墙4.1 约定前后端数据4.2 前端代码4.3 后端代码4.4 保存在数据库的版本…

超强动画制作软件blender

blender中文手册&#xff1a;Blender 4.1 Manual Blender 是一款集3D建模、渲染、动画、视频编辑、音频处理、游戏设计等多功能于一体的软件。由于其开源性质&#xff0c;它拥有庞大的用户群体和活跃的开发者社区&#xff0c;这使得Blender的功能和性能得到了不断的提升和优化…

Linux CentOS7部署ASP.NET Core应用程序,并配置Nginx反向代理服务器和Supervisor守护服务

前言&#xff1a; 本篇文章主要讲解的是如何在Linux CentOS7操作系统搭建.NET Core运行环境并发布ASP.NET Core应用程序&#xff0c;以及配置Nginx反向代理服务器。因为公司的项目一直都是托管在Window服务器IIS上&#xff0c;对于Linux服务器上托管.NET Core项目十分好奇。因为…

hot100 -- 二叉树(上)

目录 &#x1f382;二叉树的中序遍历 AC 递归 AC 迭代 &#x1f33c;二叉树的最大深度 AC DFS递归 AC BFS &#x1f6a9;翻转二叉树 AC 后序&#xff08;递归&#xff09; AC 中序 &#x1f6a9;对称二叉树 AC 递归 AC 迭代 &#x1f33c;二叉树的直径 A…

C语言之位操作符:<<、>>、、|、^、~,以及原码反码补码和例题详解

目录 前言 一、原码、反码、补码 二、移位操作符 三、位操作符&#xff1a;&、|、^、~ 四、经典例题分析&#xff1a; 总结 前言 本文将详细介绍C语言中左移操作符<<&#xff0c;右移操作符>>&#xff0c;按位与&&#xff0c;按位或|&#xff0c;按位异或^…

VS(Visual Studio)中查找项目里的中文字符

目录 正则表达式查找中文字符 正则表达式查找中文字符 在Visual Studio (VS) 中查找所有的中文字符&#xff0c;你可以使用其强大的查找和替换功能。不过&#xff0c;由于中文字符的范围非常广泛&#xff08;包括简体中文、繁体中文、日本汉字、韩国汉字等&#xff09;&#xf…

C语言——小知识和小细节17

一、未能给指针成功赋值 #include <stdio.h> #include <stdlib.h> #include <string.h>void GetMemory(char* p) {p (char*)malloc(20 * sizeof(char)); }void Test() {char* str NULL;GetMemory(str);strcpy(str, "Hello World!");printf(&quo…

计算机网络chapter2——应用层

文章目录 第2章 应用层章节引出—— 2.1应用层协议原理2.1.1 网络应用程序体系结构&#xff08;1&#xff09;客户-服务器体系结构&#xff08;2&#xff09;对等(P2P)体系结构2.1.2 进程通信1.客户和服务器进程2.进程与计算机网络之间的接口3. 进程寻址 2.1.3 可供应用程序使用…

Linux shell编程学习笔记48:touch命令

0 前言 touch是csdn技能树Linux基础练习题中最常见的一条命令&#xff0c;这次我们就来研究它的功能和用法。 1. touch命令的功能、格式和选项说明 我们可以使用命令 touch --help 来查看touch命令的帮助信息。 purpleEndurer bash ~ $ touch --help Usage: touch [OPTION]…

双指针(C++)

文章目录 1、移动零2、复写零3、快乐数4、盛最多水的容器5、有效三角形的个数6、和为s的两个数7、三数之和8、四数之和 需要理解的是&#xff0c;双指针并非只有指针&#xff0c;双指针的意思是两个位置。比如对于数组来说&#xff0c;两个下标也是双指针。当然&#xff0c;也可…

基础IO认识

回顾文件 我们之前认识文件只是在语言程度上理解&#xff0c;但是我们理解的不够彻底&#xff0c;要想真正理解文件要在os上理解。 简单代码认识 1 #include<stdio.h>2 int main(){3 FILE* fpfopen("log.txt","w");4 if(fpNULL){5 p…

【小浩算法 BST与其验证】

BST与其验证 前言我的思路思路一 中序遍历判断数组无重复递增思路二 递归边界最大值最小值的传递 我的代码测试用例1测试用例2 前言 BST是二叉树一个经典应用&#xff0c;我们常常将其用于数据的查找以及构建平衡二叉树等。今天我所做的题目是验证一颗二叉树是否为二叉搜索树&…

Web,Sip,Rtsp,Rtmp,WebRtc,专业MCU融屏视频混流会议直播方案分析

随着万物互联&#xff0c;视频会议直播互动深入业务各方面&#xff0c;主流SFU并不适合管理&#xff0c;很多业务需要各种监控终端&#xff0c;互动SIP硬件设备&#xff0c;Web在线业务平台能相互融合&#xff0c;互联互通&#xff0c; 视频混流直播&#xff0c;录存直播推广&a…

带环链表问题

带环链表就是字面意思带环的链表&#xff0c;例如以下这三种情况 练习题 1.给定一个链表&#xff0c;判断链表中是否带环. - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;快慢指针&#xff0c;慢指针走一步&#xff0c;快指针走两步&#xff0c;两个指针从链表的起…

硅片和SOI哪个研究方向更好?

知识星球&#xff08;星球名&#xff1a;芯片制造与封测社区&#xff0c;星球号&#xff1a;63559049&#xff09;里的学员问&#xff1a;我研一将要结束&#xff0c;即将进入课题组。我们课题组方向有硅片和soi两种方向&#xff0c;这两种方向该如何选择呢&#xff1f; 硅片与…

python离线安装包的方法

python离线安装包的方法 访问对应安装包的镜像文件的网站找到适合自己的whl文件安装 访问对应安装包的镜像文件的网站 https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/<包名>/找到适合自己的whl文件 安装 下载完成后&#xff0c;进入opencv_python-3.4.11.45-c…

这是一个简单网站,后续还会更新

1、首页效果图 代码 <!DOCTYPE html> <html> <head> <meta charset"utf-8" /> <title>爱德照明网站首页</title> <style> /*外部样式*/ charset "utf-8"…

标准降水指数(SPI)、标准化降水蒸发蒸腾指数(SPEI)和帕尔默干旱指数(PDSI)的下载、读取和可视化

数据下载网址&#xff1a;WWDT Data (dri.edu)https://wrcc.dri.edu/wwdt/data/PRISM/ 以SPI为例说明&#xff0c; 标准化降水指数(Standardized Precipitation Index, SPI)是由Mckee et al(.1993)分析美国科罗拉多干旱时,发现降水服从偏态分布,基于此提出了标准化降水指数。…