AOP概念 和 使用

news2024/9/21 18:43:02

目录

AOP的概念

什么是AOP?

什么是SpringAOP?

为什要⽤ AOP?

AOP的作用?

AOP的组成

通知

AOP的实现

1. 添加 Spring AOP 框架⽀持。

2. 定义切面和切点。

3. 定义通知。

切点表达式


AOP的概念

什么是AOP?

AOP(Aspect Oriented Programming):⾯向切⾯编程,它是⼀种思想,它是对某⼀类事情的 集中处理。

什么是SpringAOP?

⽽ AOP 是⼀种思想,⽽ Spring AOP 是⼀个框架,提供了⼀种对 AOP 思想的实现,它们的关系和 IoC 与 DI 类似。

为什要⽤ AOP?

在开发中,我们对于公共方法的处理分为三个阶段:

  1. 每个方法都去实现(初级)
  2. 抽取公共方法(中级)
  3. 采用AOP的方式,对代码进行无侵入是实现(高级)

因此,对于这种功能统⼀,且使⽤的地⽅较多的功能,在之前我们会抽取公共方法去实现,但是现在有更好的一个办法来处理这个问题,就是AOP。

也就是使⽤ AOP 可以扩充多个对象的某个能⼒,所以 AOP 可以说是 OOP(Object Oriented Programming,⾯向对象编程)的补充和完善。

AOP的作用?

提供声明式事务;允许用户自定义切面

AOP的组成

AOP由下边四部分组成:

切面(Aspect)

由切点(Pointcut)和通知(Advice)组成,既包含了横切逻辑的定义,也包含了连接点的定义。

连接点(Join Point)

应用执行过程中能够插入切面的一个点,这个点可以是方法调用时,抛出异常时,甚至修改字段时。切面代码可以利用这些点插入到应用的正常流程之中,并添加新的行为。

切点(Pointcut)

Pointcut的作用就是提供一组规则 来匹配Join Point,给满足规则的Join Point 添加Advice.

通知(Advice)

切面也有目标-他必须要完成的工作。在AOP中,切面的工作被称为通知。

那么是不是感觉难以理解呢?

不着急我们简单说一下, AOP使用来对某一类事情进行集中处理的,那么处理事情,这个整体就是一个切面,处理事情的范围就是切点,范围中具体的事物就是连接点,怎么处理就是通知。

简单的体系图如下:

通知

通知又名拦截器,它定义了切面是做什么以及何时使用,即在某个特定的连接点上执行的动作,它是切面的具体实现。以目标方法为参照点,根据放置位置的地方不同,通知分为如下5种类型通知:

  • 前置通知使⽤ @Before:通知⽅法会在⽬标⽅法调⽤之前执⾏。
  • 后置通知使⽤ @After:通知⽅法会在⽬标⽅法返回或者抛出异常后调⽤。
  • 返回之后通知使⽤ @AfterReturning:通知⽅法会在⽬标⽅法返回后调⽤。
  • 抛异常后通知使⽤ @AfterThrowing:通知⽅法会在⽬标⽅法抛出异常后调⽤。
  • 环绕通知使⽤ @Around:通知包裹了被通知的⽅法,在被通知的⽅法通知之前和调⽤之后执⾏⾃定义的⾏为。

AOP的实现

实现步骤如下:

1. 添加 Spring AOP 框架⽀持。

2. 定义切⾯和切点。

3. 定义通知。

具体操作如下:

1. 添加 Spring AOP 框架⽀持。

首先我们建立一个新的Springboot项目,在配置文件中添加AOP框架:

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

2. 定义切面和切点。

3. 定义通知。

定义一个切面:

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@Aspect
public class LoginAspect {
//定义切点
    @Pointcut("execution(* com.example.springaopdemo.controller.UserController.*(..))")
    public void pointcut(){}
//定义通知
    @Before("pointcut()")
    public void before(){
        log.info("do before,,,,");
    }
    @After("pointcut()")
    public void after(){
        log.info("do after.....");
    }
    @AfterReturning("pointcut()")
    public void afterReturning(){
        log.info("do afterReturning....");
    }
    @AfterThrowing("pointcut()")
    public  void afterThrowing(){
        log.info("do afterThrowing....");
    }
//这里注意,环绕式通知必须自己写返回结果
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint){
        Object oj=null;
        log.info("之前");
        try{
            oj=joinPoint.proceed();//调用目标方法
        }catch(Throwable e){
            throw new RuntimeException(e);
        }
        log.info("之后");
        return oj;
    }

@Aspect是aop框架中提供的,表示是一个切面。切面类中最先定义的是切点,用@Pointcut注解表示是一个切点,括号里边是切点表达式。后边的是五大类型的通知。分别是用五大类名称进行注解。

切点表达式:

AspectJ ⽀持三种通配符

*匹配任意字符,只匹配⼀个元素(包,类,或⽅法,⽅法参数)
..匹配任意字符,可以匹配多个元素 ,在表示类时,必须和 * 联合使⽤。
+表示按照类型匹配指定类的所有类,必须跟在类名后⾯,如 com.cad.Car+ ,表示继承该类的 所有⼦类包括本身

切点表达式由切点函数组成,execution是最常用的切点函数,语法为:

 修饰符和异常可以省略。

以上AOP部分的代码就已经完成,可以实现AOP的功能了,我们简单演示一下:

定义一个类来试一下它集中处理的实现:

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping("/login")
    public String login(){
        log.info("login..");
        return "login...";
    }
    @RequestMapping("set")
    public String setup(){
        log.info("setup...");
        return "setup....";
    }
    @RequestMapping("/logout")
    public String logout(){
        log.info("logout...");
        return "logout.....";
    }
}

在浏览器执行过后就会发现执行结果:(任意执行一个方法,这里执行第三个方法)

 可以看到五类通知的执行顺序如上,但是还有一个AfterThrowing没有看到打印,为什么呢?

这是因为AfterThrowing是在出现异常后才会进行打印的,在diamagnetic中插入一条异常代码,我们就会看到他的打印了:

以上代码能看出来了,AOP的确实一类事情的集中处理,且处理的时候不会破坏原有的代码,且允许用户自定义切面。

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

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

相关文章

工程师分享:如何解决传导干扰?

电磁干扰 EMI 中电子设备产生的干扰信号是通过导线或公共电源线进行传输&#xff0c;互相产生干扰称为传导干扰。传导干扰给不少电子工程师带来困惑&#xff0c;如何解决传导干扰&#xff1f; 找对方法&#xff0c;你会发现&#xff0c;传导干扰其实很容易解决&#xff0c;只要…

献给大一新生的JavaSE入门篇章 大三秋招JavaSE

Java反射 反射实现有哪些? Class.forName(“com.jdbc.cj.Driver.mysql”) 类名.class 对象名.getClass() 反射优缺点有哪些? 优点: 能够动态的获取类的实例&#xff0c;提高灵活性 缺点: 会降低性能&#xff0c;解决办法: 1. 如果多次创建某个对象的实例&#xff0c;使用…

Pixelmator Pro 3.3.10 Mosaic (macOS Universal) - 专业图像编辑工具

Pixelmator Pro 3.3.10 Mosaic (macOS Universal) - 专业图像编辑工具 请访问原文链接&#xff1a;https://sysin.org/blog/pixelmator-pro-3/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Pixelmator Pro 真正基于 Apple M…

机器学习算法实现(基于numpy)

《机器学习公式推导与代码实现》学习笔记&#xff0c;记录一下自己的学习过程&#xff0c;详细的内容请大家购买作者的书籍查阅。 这篇博客是将笔者边学边刷《机器学习公式推导与代码实现》的模型跟代码记录下来&#xff0c;部分地方结合自己的思考对原作者的代码有一定的改动…

【自定义图库】

sld文件 前段时间,有网友委托我帮他做一个家具的图库。 首先,做图库的方法有很多,最简单的是MFC拖控件然后自己把做好的bmp图贴进去就可以了,麻烦一点的是sld文件,最麻烦 是用blockview做。 下面先说说3种办法的区别: 首先,如果用MFC拖控件的办法,最简单也最方便,用st…

安全帽检测+反光衣检测+工作服检测数据集

安全帽检测反光衣检测工作服检测数据集下载地址分享:https://download.csdn.net/download/qq_34717531/88112870

AF 350 tyramide,AlexaFluor350 TSA,AF350酪胺,荧光标记试剂

文章资料汇总来源于&#xff1a;陕西新研博美生物科技有限公司小编MISSwu​ PART1----产品描述 AF350 tyramide&#xff08;AlexaFluor350酪酰胺&#xff09;&#xff0c;用于荧光标记的试剂&#xff0c;Tyramide信号放大&#xff08;TSA&#xff09;已被证明是一种特别通用且…

SAS-input和put的使用

在SAS中经常会遇到数值型变量与字符型变量之间进行相互转换&#xff0c;如何进行转换呢&#xff1f; 一、字符型转数值型 方法1&#xff1a;字符型变量通过运算进行转换&#xff0c;如Numeric Character * 1。运算符可以转换&#xff0c;但是会有NOTE提示&#xff0c;不推荐…

一个外贸业务员的鸡飞蛋打

最近在论坛上看到一个案例&#xff0c;案例是一个是SOHO的业务员从他朋友厂子拿货, 然后他发现他的前同事在他朋友的厂子做sales director&#xff0c;然后最近一个客户A出货&#xff0c;这个小伙伴就去他朋友的工厂做发货前的质检&#xff0c;正好碰到以前的一个同事也去他朋友…

【Docker】Docker安全性与安全实践(五)

前言&#xff1a; Docker安全性的作用和意义在于确保容器化应用程序和镜像的隔离性、保护数据和系统资源、防止恶意攻击&#xff0c;以及提高应用的整体安全性。 文章目录 1. Docker安全性1.1 隔离性1.2 镜像安全1.3 特权访问1.4 数据保护 2. Docker安全实践2.1 使用官方镜像或…

管理类联考——数学——趣味篇——可视化——安装Manim软件

Manim: 一个数学可视化的动画引擎 官网&#xff1a;https://3b1b.github.io/manim/index.html 名词解析 python3.7是python语言的解释器, 运行python程序的环境必备品. 这个没啥说的,大家都能懂. 虽然官方建议3.7,但是我用3.8发现也没问题.考虑未来的历史进程,大伙最好还是装…

Windows Subsystem for Android (WSA) 下载:在 Windows 11 上运行 Android 应用 (July 2023)

Windows Subsystem for Android (WSA) 下载&#xff1a;在 Windows 11 上运行 Android 应用 (July 2023) 适用于 Android™️ 的 Windows 子系统&#xff0c;2023 年 7 月更新&#xff1a;2306.40000.4.0 请访问原文链接&#xff1a;https://sysin.org/blog/wsa/&#xff0c;…

探讨高校公共建筑能耗监测系统的设计与应用

安科瑞 华楠 摘要&#xff1a;在资源节约型社会建设进程中&#xff0c;高校公共建筑能耗管理存在问题已经成为办学成本加大、社会资源浪费的桎梏。在各级政府的推动下&#xff0c;高校公共建筑能耗监测系统建设在探索中发展&#xff0c;依托互联网大数据技术逐步实现能耗管理信…

跨域冲突问题解决

1、问题分析 服务端和nginx代理 都做了跨域配置&#xff0c;导致请求头重复 headers 里面有两个重复的 Access-Control-Allow-Origin Access-Control-Allow-Methods Access-Control-Allow-Credentials 2、解决方法 在nginx去除服务端的跨域配置 proxy_hide_header Access-…

【腾讯云 Cloud Studio 实战训练营】CloudStudio体验真正的现代化开发方式,双手插兜不知道什么叫对手!

CloudStudio体验真正的现代化开发方式&#xff0c;双手插兜不知道什么叫对手&#xff01; 文章目录 CloudStudio体验真正的现代化开发方式&#xff0c;双手插兜不知道什么叫对手&#xff01;前言出现的背景一、CloudStudio 是什么&#xff1f;二、CloudStudio 的特点三、CloudS…

医学案例|配对wilcoxon符号秩检验

一、案例介绍 某单位想要研究某保健品对小鼠是否具有抗疲劳作用&#xff0c;将同种属的小鼠按性别与年龄相同、体重相近配成对子&#xff0c;共14对&#xff0c;并将每对中的两只小鼠随机分配到两个不同的保健食品剂量组&#xff0c;测量小鼠负重5&#xff05;体重时的游泳时间…

通过IDEA发送QQ邮箱信息

先创建一个普通的Maven项目&#xff0c;我就不演示啦&#xff0c;个人博客已经写过~[创建一个maven项目]。 项目创建成功后&#xff0c;引人Maven依赖&#xff0c;如下: <dependencies><dependency><groupId>org.apache.commons</groupId><artifact…

力扣天天练week3-LeetCode75

topic75-1-t1768交替合并字符串 题目描述&#xff1a;给你两个字符串word1和word2。请你从 word1 开始&#xff0c;通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长&#xff0c;就将多出来的字母追加到合并后字符串的末尾。返回 合并后的字符串 。 示例&#…

Exadata磁盘损坏导致磁盘组无法mount恢复(oracle一体机磁盘组异常恢复)---惜分飞

Oracle Exadata客户,在换盘过程中,cell节点又一块磁盘损坏,导致datac1磁盘组&#xff08;该磁盘组是normal方式冗余)无法mount Thu Jul 20 22:01:21 2023 SQL> alter diskgroup datac1 mount force NOTE: cache registered group DATAC1 number1 incarn0x0728ad12 NOTE: ca…

【Untity】通过子物体坐标和父物体Transfrom,计算子物体的世界坐标

如图 父物体Transfrom信息如下 子物体坐标如下 代码如下 将pos点&#xff0c;基于父物体scale进行缩放。 在用父物体旋转量* pos 再加上父物体的坐标。 即为子物体的世界坐标。 void Start(){Vector3 pos new Vector3(1, 2, 3);Vector3 parentPos new Vector3(10, 20, 30)…