【Spring】认识 Spring AOP

news2024/9/21 8:04:06

认识 Spring AOP

  • 1.什么是 AOP
  • 2.AOP 中的概念
  • 3.用 AOP 方式管理日志
    • 3.1 编写 AOP 日志注解类
    • 3.2 编写控制器用于测试

1.什么是 AOP

AOP(Aspect Oriented Program面向切面编程)把业务功能分为核心、非核心两部分。

  • 核心业务功能:用户登录、增加数据、删除数据。
  • 非核心业务功能:性能统计、日志、事务管理。

在 Spring 的面向切面编程(AOP)思想里,非核心业务功能 被定义为 切面。核心业务功能和切面功能先被分别进行独立开发,然后把切面功能和核心业务功能 编织 在一起,这就是 AOP。
在这里插入图片描述
由此可见,AOP 将业务无关,却为业务模块所共同调用的逻辑封装起来,以便减少系统的重复代码,降低模块间的耦合度,利于未来的拓展和维护。这正是 AOP 的目的,它是 Spring 最为重要的功能之一,被广泛使用。

2.AOP 中的概念

  • 切入点pointcut):在哪些类、哪些方法上切入。
  • 通知advice):在方法前、方法后、方法前后做什么。
  • 切面aspect):切面 = 切入点 + 通知。即在什么时机、什么地方、做什么。
  • 织入weaving):把切面加入对象,并创建出代理对象的过程。
  • 环绕通知:AOP 中最强大、灵活的通知,它集成了前置和后置通知,保留了连接点原有的方法。

3.用 AOP 方式管理日志

下面通过实例演示如何用 AOP 方式管理日志。

3.1 编写 AOP 日志注解类

package com.example.demo.aop;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;


/**
 * Description:  使之成为切面类
 */
@Aspect
/**
 * Description: 把切面类加入到IOC容器中
 */
@Component
public class AopLog {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    //线程局部的变量,解决多线程中相同变量的访问冲突问题。
    ThreadLocal<Long> startTime = new ThreadLocal<>();
    //定义切点
    @Pointcut("execution(public * com.example..*.*(..))")
    public void aopWebLog() {
    }

    @Before("aopWebLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        startTime.set(System.currentTimeMillis());
        // 接收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 记录下请求内容
        logger.info("URL : " + request.getRequestURL().toString());
        logger.info("HTTP方法 : " + request.getMethod());
        logger.info("IP地址 : " + request.getRemoteAddr());
        logger.info("类的方法 : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        //logger.info("参数 : " + Arrays.toString(joinPoint.getArgs()));
        logger.info("参数 : " + request.getQueryString());
    }

    @AfterReturning(pointcut = "aopWebLog()",returning = "retObject")
    public void doAfterReturning(Object retObject) throws Throwable {
        // 处理完请求,返回内容
        logger.info("应答值 : " + retObject);
        logger.info("费时: " + (System.currentTimeMillis() - startTime.get()));
    }

    //抛出异常后通知(After throwing advice) : 在方法抛出异常退出时执行的通知。
    @AfterThrowing(pointcut = "aopWebLog()", throwing = "ex")
    public void addAfterThrowingLogger(JoinPoint joinPoint, Exception ex) {
        logger.error("执行 " + " 异常", ex);
    }

}
  • @Before:在切入点开始处切入内容。
  • @After:在切入点结尾处切入内容。
  • @AfterReturning:在切入点 return 内容之后切入内容(可以用来对处理返回值做一些加工处理)。
  • @Around:在切入点前后切入内容,并自己控制何时执行切入点自身的内容。
  • @AfterThrowing:用来处理当切入内容部分抛出异常之后的处理逻辑。
  • @Aspect:标记为切面类。
  • @Component:把切面类加入到 IOC 容器中,让 Spring 进行管理。

3.2 编写控制器用于测试

下面的控制器构造了一个普通的 Rest 风格的页面。

package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AopLogController {
    @GetMapping("/aoptest")
    public String aVoid(){
        return "hello aop test";
    }
}

启动项目,访问 http://localhost:8080/aoptest

在这里插入图片描述
在控制台会输出如下信息。

在这里插入图片描述

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

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

相关文章

Spark-RDD-依赖关系详解

Spark概述 Spark-RDD概述 Spark-RDD-依赖关系 在Apache Spark中&#xff0c;RDD&#xff08;Resilient Distributed Dataset&#xff09;是一种基本的抽象数据结构&#xff0c;代表了分布式的、不可变的数据集。 RDD之间的依赖关系在Spark中非常重要&#xff0c;因为它们决定了…

YOLO 学习和使用 (重拾机器学习)

contents a nenrons 单层神经网络 多层神经网络 CNN (Convolutional Neural Network) YOLO 5.1. YOLO(you only look once) 5.2. predict stage: 置信度 * 类别条件概率 全概率非极大值抑制&#xff0c;通过IOU 指数进行实现每个 grid cell 生成两个预测 bounding box 无…

4. C++网络编程-TCP客户端的实现

TCP Client网络编程基本步骤 创建socket&#xff0c;指定使用TCP协议使用connect连接服务器使用recv/send接收/发送数据关闭socket TCP-connect连接请求 !man 2 connect #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int connect(int sock…

Java面试题--JVM大厂篇(1-10)

引言&#xff1a; 在这个信息时代&#xff0c;对于准备进入大厂工作的朋友们来说&#xff0c;对于JVM&#xff08;Java虚拟机&#xff09;的掌握是面试中的一项重要内容。下面是一些精选的JVM面试题&#xff0c;希望对大家能有所帮助。 正文&#xff1a; 1. JVM有哪几种垃圾收…

车道线识别与预警系统LDWS(代码+教程)

车道线识别与预警系统&#xff08;Lane Departure Warning System, LDWS&#xff09;作为智能交通系统中的重要组成部分&#xff0c;旨在通过先进的图像处理和计算机视觉技术&#xff0c;实时监测车辆行驶过程中的车道位置&#xff0c;预防因驾驶员疏忽或疲劳导致的车道偏离事故…

自己手写了一个大模型RAG项目-06.使用自己的embedding模型

大家好&#xff0c;我是程序锅。 github上的代码封装程度高&#xff0c;不利于小白学习入门。 常规的大模型RAG框架有langchain等&#xff0c;但是langchain等框架源码理解困难&#xff0c;debug源码上手难度大。 因此&#xff0c;我写了一个人人都能看懂、人人都能修改的大…

Unity入门理论+实践篇之Luna

创建世界的主角 父子物体 首先创建一个cube物体 可以观察到其在2D视角下的坐标为&#xff08;0&#xff0c;0&#xff09; 此时将cube物体拖拽到ldle_0下&#xff0c;如图所示&#xff0c;并将其坐标值改为&#xff08;2&#xff0c;2&#xff09; 此时再将ldle_0物体的坐标…

拓数派入选中电联大数据与统计分会两大重点专项工作组

自中国电力企业联合会大数据与统计分会成立以来&#xff0c;深入贯彻党中央、国务院关于不断做强做优做大我国数字经济有关要求&#xff0c;充分发挥数据要素乘数效应&#xff0c;凝聚行业专家及能源电力产业链各主体力量&#xff0c;持续推进能源电力数据资源交易共享&#xf…

Unity环绕物体的摄像机,添加了遮挡的适应

第三人人称摄像机 支持的功能 设定目标后使用鼠标可以环绕目标点旋转&#xff0c;且会进行遮挡的适配&#xff0c;当有遮挡的时候会移动差值移动到没有遮挡的位置。 使用方式 将vThirdPersonCamera 挂在与摄像机上然后为target赋值。 如果有需要检测遮挡的层级可以修改&…

数据仓库与数据挖掘实验练习6-7(实验四2024.5.22)

tips&#xff1a; 列出虚拟环境&#xff1a;conda env list 激活虚拟环境&#xff1a;activate hi 进入jupyter-lab&#xff1a;jupyter lab 练习6 1. 处理字符串空格 发现问题: 使用 values 属性查看数据时&#xff0c;如果发现 Name 列没有对齐&#xff0c;很可能是 Name 左…

2024年软考总结 信息系统管理师

选择题 英文题&#xff0c;我是一题也没把握&#xff0c;虽然我理解意思。 千万不要认为考死记硬背不对。目的不在于这。工程项目中有很多重要的数字&#xff0c;能记住说明你合格。 案例 几乎把答案全写在案例中了。 计算题 今年最简单。没有考成本。 只考了关键路径&a…

sheng的学习笔记-AI-EM算法

AI学习笔记目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 目录 基础知识 什么是EM算法 EM算法简介 数学知识 极大似然估计 问题描述 用数学知识解决现实问题 最大似然函数估计值的求解步骤 Jensen不等式 定义 EM算法详解 问题描述 EM算法推导流程 EM算法流程…

绘制t-SNE图

什么是t-SNE图&#xff1f; 如下图&#xff0c;下图来源于论文Contrastive Clustering 一般用于分类问题/对比学习。 作用&#xff1f; 体现出经过层层训练&#xff0c;类内越来越紧密&#xff0c;类间差异越来越大&#xff1b;或者也可以做消融可视化。 怎么画&#xff1f…

如何安装虚拟机Wmware,并且在虚拟机中使用centos系统

1. 前言 大家好&#xff0c;我是jiaoxingk 本篇文章主要讲解如何安装虚拟机&#xff0c;并且在虚拟机中安装centos系统&#xff0c;让windows电脑也能够使用Linux系统 2. 虚拟机的介绍 在安装Vmware之前&#xff0c;我们先做虚拟机的介绍 虚拟机&#xff1a;通过软件虚拟出来的…

【吊打面试官系列】Java高并发篇 - 什么是乐观锁和悲观锁?

大家好&#xff0c;我是锋哥。今天分享关于 【什么是乐观锁和悲观锁?】面试题&#xff0c;希望对大家有帮助&#xff1b; 什么是乐观锁和悲观锁? 1、乐观锁&#xff1a; 就像它的名字一样&#xff0c;对于并发间操作产生的线程安全问题持乐观状态&#xff0c; 乐观锁认为竞争…

JAVAEE初阶多线程(4)

在前面的文章中简单的概述了线程的基本定义接下来就是线程的最后完结了。 1.工厂模式 1.1工厂模式的简单定义 &#xff08;1&#xff09;在java jar包中有一个工厂模式这是一种设计模式 &#xff08;2&#xff09;这个设计模式是为了更好的解决构造方法创建对象太坑了的问题…

安卓开发:相机水印设置

1.更新水印 DecimalFormat DF new DecimalFormat("#"); DecimalFormat DF1 new DecimalFormat("#.#");LocationManager LM (LocationManager)getSystemService(Context.LOCATION_SERVICE); LM.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2…

urllib_post请求_百度翻译之详细翻译

百度翻译有一个详细翻译的接口&#xff1a; post请求&#xff1a; 请求参数&#xff08;较多&#xff09;&#xff1a; 打印之后&#xff0c;发现有问题&#xff1a; 改一下请求头&#xff1a; 将Accept-Encoding注释掉&#xff0c;因为我们使用的是utf-8编码&#xff1a; 加上…

解决:LVGL+GUI Guider 1.7.2运行一段时间就会卡死死机,内存泄露溢出的问题

概括&#xff1a; 我在使用NXP官方GUI Guider生成的代码出现了内存泄漏的问题。但我遇到的并不是像其他人所说的style的问题&#xff0c;如下链接。而是因为在页面渲染之前就使用了该页面内的组件&#xff0c;内存就会不断增加。 LVGL 死机 内存泄漏_lvgl 内存溢出-CSDN博客 运…

..堆..

堆 堆是完全二叉树&#xff0c;即除了最后一列之外&#xff0c;上面的每一层都是满的&#xff08;左右严格对称且每个节点都满子节点&#xff09; 最后一列从左向右排序。 默认大根堆&#xff1a;每一个节点都大于其左右儿子&#xff0c;根节点就是整个数据结构的最大值 pr…