通俗易懂的案例+代码解释AOP 切面编程

news2024/12/23 17:48:19

目录

  • 1. 理解AOP
  • 2 @ Before
    • 2.1 controller层
    • 2.2 service层
    • 2.3 自定义注解
    • 2.4 切面 advice
  • 3 @ After
  • 4 @ Around

spring的三大核心:IOC控制反转、DI依赖注入、AOP面向切面编程
刚开始接触springboot项目,前两个使用的多,亲自使用AOP的机会并不多,在解决埋点bug时恰好遇到,特此梳理出来

1. 理解AOP

补充一点,这里切入就是插入的意思
参考博文,点击查看

参考博文,这篇文章的解释十分到位,本文就不多赘述什么是AOP。这里原作者解释不够严谨,记录操作日志应该在最后插入。
在这里插入图片描述

2 @ Before

2.1 controller层

@RestController
@RequestMapping("/a")
public class demo {

    @Resource
    private MyService myService;

    @ResponseBody
    @RequestMapping(value = "/b", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public void getPolicyFile(@RequestParam("name") String name, @RequestParam("age") Integer age) {
        myService.msgShow(name,age);
    }
}

2.2 service层

Loggable是自定义的注解

@Service
public class MyService {

    @Loggable
    public void msgShow(String name,int age) {
        System.out.println("这是service的输出结果");
    }

}

2.3 自定义注解

/**
 * @Description 定义注解:Loggable
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Loggable {

}

2.4 切面 advice

@Aspect
@Component
public class LoggingAspect {

    // 定义一个切点(自定义注解的路径),表示被该注解修饰的方法都会注入advice
    @Pointcut("@annotation(com.zjh.practice.AOP.Loggable)")
    private void logPointcut() {
    }


	// joinPoint的作用就是获取msgShow()方法的参数
    @Before("logPointcut()")
    public void logadvice(JoinPoint joinPoint){

        // 这里只是一个示例,你可以写任何处理逻辑
        System.out.println("---------Before触发了----------");

        // 获取签名
        Signature signature = joinPoint.getSignature();
        // 获取切入的包名
        String declaringTypeName = signature.getDeclaringTypeName();
        // 获取即将执行的方法名
        String funcName = signature.getName();
        System.out.println(String.format("即将执行方法为: %s ,属于%s包", funcName, declaringTypeName));

        Object[] args = joinPoint.getArgs();
        String itemName = (String) args[0];
        int quantity = (int) args[1];
        System.out.println(String.format("获取的参数是%s,%d",itemName,quantity));

    }
}

输出效果


---------Before触发了----------
即将执行方法为: msgShow ,属于com.zjh.practice.AOP包
获取的参数是张三,21
这是service的输出结果

3 @ After

将@Before 换成 @After 有什么变化吗

输出效果


这是service的输出结果  (注意这条输出的位置)
---------After触发了----------
即将执行方法为: msgShow ,属于com.zjh.practice.AOP包
获取的参数是张三,21

4 @ Around

@Before只能控制在方法前执行,@After只能控制在方法后执行,那若想一起控制呢,就必须使用@Around

假设你有一个服务类 MyService,其中有一个 divide 方法执行除法操作。我们将创建一个 @Around 切面,拦截这个方法的执行,执行一些自定义逻辑,处理方法之前和之后的情况,以及异常。以下是例子:

@Aspect
@Component
public class DivisionAspect {

    @Around("execution(* com.example.service.MyService.divide(..))")
    public Object aroundDivideOperation(ProceedingJoinPoint joinPoint) throws Throwable {
        // 在方法执行前
        System.out.println("执行除法操作前");

        try {
            // 获取方法参数
            Object[] args = joinPoint.getArgs();
            if (args.length == 2 && (int) args[1] == 0) {
                // 自定义逻辑:处理除以零的情况
                System.out.println("检测到除以零。返回默认结果。");
                return 0;
            }

            // 继续执行原始方法
            Object result = joinPoint.proceed();

            // 在方法执行后
            System.out.println("执行除法操作后");

            // 如果需要,可以修改或替代原始结果
            // 为简单起见,我们将原始结果无修改地返回
            return result;
        } catch (Exception e) {
            // 异常处理:记录异常并重新抛出
            System.out.println("执行除法操作时发生异常:" + e.getMessage());
            throw e;
        } finally {
            // 清理或额外的逻辑,无论如何都会执行
            System.out.println("在执行除法操作后的finally块");
        }
    }
}

现在,假设你有一个 MyService 类如下:

package com.example.service;

import org.springframework.stereotype.Service;

@Service
public class MyService {

    public int divide(int dividend, int divisor) {
        // 模拟除法操作
        return dividend / divisor;
    }
}

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

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

相关文章

python自动化测试如何做数据缓存 ?这个第三方包推荐给你,方便又简单!

1.数据缓存说明 数据缓存可以说也是项目开发中比不可少的一个工具 ,像我们测试的系统中 ,你都会见到像Redis一样的数据缓存库 。使用缓存数据库的好处不言而喻,那就是效率高 ,简单数据直接放在缓存中 ,存取简单方便 。…

探索Scrapy-spider:构建高效网络爬虫

Spider简介 Scrapy中的Spider是用于定义和执行数据抓取逻辑的核心组件。Spider负责从指定的网站抓取数据,并定义了如何跟踪链接、解析内容以及提取数据的规则。它允许您定制化地指定要抓取的网站、页面和所需的信息。Spider的作用是按照预定的规则爬取网页&#xf…

12.7 C++作业

自由发挥登录窗口的应用场景,实现一个登录窗口界面 #include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {//*******窗口相关设置********this->setWindowTitle("王者农药"); //设置窗口标题this->setWindowIcon(QIc…

OpenTiny Vue 3.12.0 发布:文档大优化!增加水印和二维码两个新组件

你好,我是 Kagol。 非常高兴跟大家宣布,2023年11月30日,OpenTiny Vue 发布了 v3.12.0 🎉。 OpenTiny 每次大版本发布,都会给大家带来一些实用的新特性,10.24 我们发布了 v3.11.0 版本,增加了富…

算法学习系列(六):高精度加法、减法、乘法、除法

目录 引言一、高精度加法1.题目描述2.代码实现3.测试 二、高精度减法1.题目描述2.代码实现3.测试 三、高精度乘法1.题目描述2.代码实现3.测试 四、高精度除法1.题目描述2.代码实现3.测试 引言 本文介绍了高精度加法、高精度减法、高精度乘法、高精度除法,这个高精度…

【Java数据结构 -- List和ArrayList与顺序表】

List和ArrayList与顺序表 一. List1.1 List介绍2.1 常见接口介绍3.1 List的使用 二. ArrayList与顺序表1.线性表2.顺序表2.1 接口的实现 3.ArrayList简介4. ArrayList使用4.1 ArrayList的构造 4.2 ArrayList常见操作4.3 ArrayList的遍历4.4 ArrayList的扩容机制5. ArrayList的具…

Python 网络爬虫(二):HTTP 基础知识

《Python入门核心技术》专栏总目录・点这里 文章目录 1. HTTP 协议简述2. HTTP 请求过程3. HTTP 的结构3.1 请求行3.2 请求头3.3 请求体3.4 状态行3.5 响应头3.6 响应体4. Cookie 状态管理5. HTTP 请求示例6. 总结<

HTML5+CSS3小实例:3D翻转Tab选项卡切换特效

实例:3D翻转Tab选项卡切换特效 技术栈:HTML+CSS 效果: 源码: 【HTML】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content=…

【Linux】公网远程访问AMH服务器管理面板

目录 1. Linux 安装AMH 面板2. 本地访问AMH 面板3. Linux安装Cpolar4. 配置AMH面板公网地址5. 远程访问AMH面板6. 固定AMH面板公网地址 AMH 是一款基于 Linux 系统的服务器管理面板&#xff0c;它提供了一系列的功能&#xff0c;包括网站管理、FTP 管理、数据库管理、DNS 管理、…

信号完整性分析

目录 前言一、信号完整性SI1.1 信号失真1.2 串扰1.3 衰减 二、电源完整性PI2.1 地弹2.2 电源轨道塌陷 三、电磁兼容EMC3.1 电磁辐射3.2 抗干扰 前言 本篇介绍信号完整性分析的知识体系&#xff0c;以及部分分析方法。   什么是信号完整性?通俗来讲&#xff0c;信号在互连线的…

若依角色与权限字符串

文章目录 一、简介1.基于权限字段串2.基于角色 二、若依的权限控制1.介绍2.实践 一、简介 基于权限字段串和基于角色的访问控制是两种不同的权限管理模型&#xff0c;它们各自有其优点和应用场景。下面是这两种模型的基本概念&#xff1a; 1.基于权限字段串 基于权限字段串&…

基于ssm实验室课程管理系统源码和论文

idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 环境&#xff1a; jdk8 tomcat8.5 摘 要 随着科学实验规模的不断扩大&#xff0c;实验室课程数量的急剧增加&#xff0c;有关实验室课程的各种信息量也在不断成倍增长。面对庞大的信息量&#xff0c;就需要有…

SpringCloud简介和用处

Spring Cloud是一套基于Spring Boot的微服务框架&#xff0c;它旨在提供一种快速构建分布式系统的方法。它可以帮助开发人员构建具有高可用性、可扩展性和容错性的微服务&#xff0c;并通过Spring Boot的开发工具和库提供强大的支持。 一、简介 Spring Cloud是Spring家族中的一…

Spark Structured Streaming使用教程

文章目录 1、输入数据源2、输出模式3、sink输出结果4、时间窗口4.1、时间窗口4.2、时间水印&#xff08;Watermarking&#xff09; 5、使用例子 Structured Streaming是一个基于Spark SQL引擎的可扩展和容错流处理引擎&#xff0c;Spark SQL引擎将负责增量和连续地运行它&#…

2023-2024-1-高级语言程序设计-第2次月考编程题

注&#xff1a;此前已发布过的题解不再发布&#xff08;原题请在下面位置进行搜索&#xff09;。 7-1-2 排序(算法任意) 本题要求将给定的n个整数从大到小排序后输出&#xff08;可使用任意排序算法&#xff09;。 输入格式: 输入第一行给出一个不超过10的正整数n。第二行给…

WVP-RPO开源项目搭建实践

0.拉取代码 GitHub - 648540858/wvp-GB28181-pro: WEB VIDEO PLATFORM是一个基于GB28181-2016标准实现的网络视频平台&#xff0c;支持NAT穿透&#xff0c;支持海康、大华、宇视等品牌的IPC、NVR、DVR接入。支持国标级联&#xff0c;支持rtsp/rtmp等视频流转发到国标平台&…

详细解读电力DLT698.45-2017通信规约--正向有功总电能

建立连接请看这篇&#xff1a;详细解读DLT698.45-2017通信规约--预连接响应http://mp.weixin.qq.com/s?__bizMzA3NjAwMjQzMQ&mid2652026396&idx1&sna0a17f005d23136c922a7c381ddb7e75&chksm8481f30cb3f67a1a94e66db77e61fe73c22b1904fcdbb0144108e132b265e7b4…

dtaidistance笔记:dtw_ndim (高维时间序列之间的DTW)

1 数据 第一个维度是sequence的index&#xff0c;每一行是多个元素&#xff08;表示这一时刻的record&#xff09; from dtaidistance.dtw_ndim import *s1 np.array([[0, 0],[0, 1],[2, 1],[0, 1],[0, 0]], dtypenp.double) s2 np.array([[0, 0],[2, 1],[0, 1],[0, .5],[0…

水果党flstudio用什么midi键盘?哪个版本的FL Studio更适合我

好消息&#xff01;好消息&#xff01;特大好消息&#xff01; 水果党们&#xff01;终于有属于自己的专用MIDI键盘啦&#xff01; 万众期待的Novation FLKEY系列 正式出炉&#xff01; 话有点多话&#xff0c;先分享一份干货&#xff0c;尽快下载 FL Studio 21 Win-安装包&…

搜索推荐技术-爱奇艺搜索引擎技术

一、爱奇艺的搜索引擎框架示意图 即通过召回系统&#xff0c;即基于文本匹配的matching system&#xff0c;得到大量视频资源的候选集&#xff0c;经过粗排和精排&#xff0c;最后返回给用户。重点在于召回模块和排序模块。 二、召回模块 召回模块比较重要的是基础相关性&am…