Spring框架学习day5--AOP概念以及示例实现

article/2025/7/29 20:37:18

AOP(面向切面编程)

1.概述

AOP为AspectOrientedProgramming 的缩写,意为:面向切面编程,通过 预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。 AOP是OOP的延续,是软件开发中的一个热点,是java开发中的一个重要内 容。利用AOP可以对业务逻辑和非业务逻辑进行隔离,从而使得各部分之间的 耦合度降低,提高程序的可重用性,同时提高了开发的效率。

​ AOP、OOP在字面上虽然非常类似,但却是面向不同领域的两种设计思想。OOP (面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获 得更加清晰高效的逻辑单元划分。 而AOP则是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的 某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。这两种设 计思想在目标上有着本质的差异。

面向切面编程的好处就是: 减少重复,专注业务;

将业务代码和非业务代码分开

Reader reader = null;try {/*非业务代码*/reader = Resources.getResourceAsReader("mybatis.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);SqlSession sqlSession = sqlSessionFactory.openSession();/* 业务代码*/S_studentDao studentDao =sqlSession.getMapper(S_studentDao.class);System.out.println("班级id=2学生信息");ArrayList<S_student> sStudents = studentDao.getStudentsByClassId(2);for (S_student sStudent : sStudents) {System.out.println(sStudent);}/*非业务代码*/sqlSession.commit();sqlSession.close();} catch (IOException e) {throw new RuntimeException(e);}}

注意:面向切面编程只是面向对象编程的一种补充。

核心原理:

使用动态代理的方式在执行方法前后或者出现异常的时候做加入相关的逻辑.

使用案例:

事务处理:开启事务,关闭事务,出现异常后回滚事务

权限判断:在执行方法前,判断是否具有权限

日志:在执行前进行日志处理

image-20250531153007477

这样我们就做到了 业务代码 与 非业务代码进行隔离,实现低耦合度

总结:面向切片编程,是一种将非业务代码与业务代码进行分离的一种思想,在实际开发中,往往许多重复操作,例如事务提交,权限验证,保存日志等功能

面向切片变成,就是将非业务代码进行抽取,然后在不修改原来代码的前提下,为我们的业务代码添加额外的功能

底层使用的是动态代理技术,让代理对象,帮助我们调用非业务代码

AOP思想不是spring特有的,是java中的动态代理模式,是spring框架中使用这一思想

2.概念

连接点(Joinpoint):类中可以被增强的方法(可以添加额外功能的方法),这个方法就被称为连接点

(增强:增加额外的方法)

切入点(pointcut):类中有很多方法可以被增强,但实际中只有add和update 被增强了,那么add和update方法就被称为切入点(实际实现的连接点)

通知(Advice): 通知是指一个切面在特定的连接点要做的事情(增强的功能)。通 知分为方法执行前通知,方法执行后通知,环绕通知等.

目标(Target): 代理的目标对象(连接点,切入点所在类)

代理(Proxy): 向目标对象应用通知时创建的代理对象(目前所使用的代理对象由Spring框架生成,不需要我们去关心)

3.springAOP 实现(AspectJ框架)

对于 AOP 这种编程思想,很多框架都进行了实现。Spring 就是其中之一,
可以完成面向切面编程。

AspectJ 是一个基于Java语言的AOP框架,它提供了强大的AOP功能,且其实
现方式更为简捷,使用更为方便, 而且还支持注解式开发。所以,Spring 又
将 AspectJ 的对于 AOP 的实现也引入到了自己的框架中。

下载AOP相关jar

<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.2.2.RELEASE</version>
</dependency>

AspectJ 中常用的通知有五种类型:

前置通知,后置通知,环绕通知,异常通知,返回通知.

  • @Before前置通知:方法执行之前

  • @After后置通知:方法执行之后,无论是否出现异常

  • @AfterReturnning返回通知:方法成功执行之后通知,出现异常不执行

  • @AfterThrowing异常通知:抛出异常之后通知

  • @Around环绕通知:方法执行前后都有通知

基于注解方式的实现 启动AspectJ支持:

<aop:aspectj-autoproxy/>

image-20250531231350729

image-20250531231403407

@After 与 @AfterReturning 区别:After 无论方法是否正常执行都会执行,AfterReturning 只在方法正常执行后才执行。

配置案例具体分析

总体框架:

image-20250531231818640

只需要配置spring.xml与pom.xml即可

spring.xml
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--        开启注解扫描  对指定包下的注解进行扫描 ,检查添加spring类注解标签的类--><context:component-scan base-package="org.example"/><!--       开启自动代理--><aop:aspectj-autoproxy/></beans>
pom.<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>spring2</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies>
<!--        AOP实现依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.2.2.RELEASE</version></dependency><!--spring-context--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.2.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.2.RELEASE</version></dependency><!-- spring-jdbc--><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.2.2.RELEASE</version></dependency><!-- 阿里数据源--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version></dependency><!--        mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.2</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.1</version></dependency></dependencies></project>xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>spring2</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies>
<!--        AOP实现依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.2.2.RELEASE</version></dependency><!--spring-context--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.2.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.2.RELEASE</version></dependency><!-- spring-jdbc--><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.2.2.RELEASE</version></dependency><!-- 阿里数据源--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version></dependency><!--        mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.2</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.1</version></dependency></dependencies></project>

AdminDao类

package org.example.dao;import org.example.comment.LogUtil;
import org.springframework.stereotype.Repository;@Repository
public class AdminDao {public void saveAdmin(){System.out.println("Admin saved successfully");
//        new LogUtil().saveLogin();}public void deleteAdmin(){System.out.println("Admin deleted successfully");}public void updateAdmin(){System.out.println("Admin updated successfully");
//        new LogUtil().commit();}}

LogUtil类

package org.example.comment;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;import java.util.Arrays;@Component //spring管理生成LogUtil对象
@Aspect //添加此标签类中的方法就是代理对象要调用的方法
public class LogUtil {
//    @Before("execution(* org.example.dao.AdminDao.saveAdmin(..))")@Before("execution(* org.example.dao.AdminDao.*(..))")//AdminDao层所有方法都记录日志public void saveLogin() {System.out.println("this is Login saved log!!!");}@After("execution(* org.example.dao.AdminDao.*(..))")/*After 与 AfterReturning 区别:After 无论方法是否正常执行都会执行,而 AfterReturning 只在方法正常执行后才执行。*/public void commit() {System.out.println("Transaction committed");}//    @AfterThrowing("execution(* org.example.dao.AdminDao.*(..))")
//    public void exception1() {
//        System.out.println("Exception occurred");
//    }@AfterThrowing(value = "execution(* org.example.dao.AdminDao.*(..))",throwing = "e")public void exception2(Throwable e) {System.out.println("Exception occurred");}/** 环绕通知:* 环绕通知是指在方法调用前后以及异常调用的通知都要执行的通知,可以用来对方法进行拦截、修改或增强。* 环绕通知的定义格式为:* */@Around("execution(* org.example.dao.AdminDao.*(..))")public Object around(ProceedingJoinPoint joinPoint) {System.out.println("before around");Object result = null;try {System.out.println("保存日志");//前置通知Object[] args = joinPoint.getArgs();//获取方法参数System.out.println("参数:" + Arrays.toString(args));result = joinPoint.proceed();//调用我们自己的方法System.out.println("提交事务");//返回通知} catch (Throwable e) {e.printStackTrace();//异常通知}System.out.println("after around");//后置通知return result;}
}

AdminService

package org.example.service;import org.example.dao.AdminDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service("adminService")
public class AdminService {@AutowiredAdminDao adminDao;public void saveAdmin(){adminDao.saveAdmin();}public void deleteAdmin(){adminDao.deleteAdmin();}public void updateAdmin(){adminDao.updateAdmin();}
}

test类

package org.example.test;import org.example.service.AdminService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class test {public static void main(String[] args) {
//        AdminService adminService = new AdminService();
//        adminService.saveAdmin();
//        adminService.updateAdmin();ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");AdminService adminService = (AdminService) context.getBean("adminService");adminService.saveAdmin();}
}

运行结果:

image-20250601003637372


http://www.hkcw.cn/article/fojQLRCIDO.shtml

相关文章

Python实现HPSO-TVAC优化算法优化支持向量机SVC分类模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在当今数据驱动的时代&#xff0c;支持向量机&#xff08;SVM&#xff09;作为一种经典的机器学习算法&#xff0c;…

警方回应10岁男孩儿童节前走失 仍在全力搜寻中

6月1日,山东省滕州市姜屯镇黄坡村一名10岁的小男孩赵某超走失,孩子家属通过网络社交媒体求助。事后家属查看家门口的监控发现,孩子是5月31日下午5时左右走失的。当时孩子消失在家门口的监控中后几分钟返回了一次,孩子的外公王先生在屋后的黄瓜地里插杆子,邻居还给了孩子一…

[SAP] 矩阵复制(Matrix Copy)

SAP中的复制粘贴功能被称为矩阵复制&#xff0c;通过点击对话框或屏幕&#xff0c;并执行下述命令&#xff0c;使用矩阵复制就可以复制多行文本 ① 按下Ctrl-Y&#xff0c;从左上到右下拖拉鼠标来选择文本 ② 文本高亮显示后&#xff0c;按下Ctrl-C ③ 移到新的位置插入文本…

2024年数维杯国际大学生数学建模挑战赛B题空间变量协同估计方法研究解题全过程论文及程序

2024年数维杯国际大学生数学建模挑战赛 B题 空间变量协同估计方法研究 原题再现&#xff1a; 在数理统计学中&#xff0c;简单采样通常假设来自相同总体的采样点彼此独立。与数理统计相反&#xff0c;空间统计假设空间变量的采样点是相依的&#xff0c;并在其值中表现出某些趋…

SPA-RL:通过Stepwise Progress Attribution训练LLM智能体

SPA-RL&#xff1a;通过Stepwise Progress Attribution训练LLM智能体 在大语言模型&#xff08;LLM&#xff09;驱动智能体发展的浪潮中&#xff0c;强化学习&#xff08;RL&#xff09;面临着延迟奖励这一关键挑战。本文提出的SPA-RL框架&#xff0c;通过创新的分步进度归因机…

基于 Zynq 平台的 EtherCAT 主站的软硬件协同设计

摘要: 针对工业自动化对控制能力和强实时性的需求&#xff0c;提出了一种基于 FPGA 的改进型 EtherCAT 硬件主站方案 。 该方案利用 Zynq&#xff0d;7000 平台&#xff0c;在 PL 端实现 FPGA 协议栈&#xff0c;以保证核心功能的高效执 行 。 基于 AXI4 总线设计…

【IC】BSIM-CMG:用于高级电路设计的标准FinFET紧凑型模型

摘要 这项工作提出了新的紧凑型模型&#xff0c;这些模型捕捉了工业FinFET中呈现的高级物理效应。所提出的模型被引入到行业标准紧凑型模型BSIM-CMG中。核心模型被更新为新的统一FinFET模型&#xff0c;该模型计算具有复杂鳍片横截面的晶体管的电荷和电流。此外&#xff0c;来…

BFD工作原理(双向转发检测)

BFD的工作原理 BFD 会在两台网络设备之间建立会话&#xff0c;并通过周期性地交换 BFD 控制报文来检测路径的连通性。如果在检测时间内没有收到对方的报文&#xff0c;则视为链路故障&#xff0c;是依赖于路由协议来发现邻居的 故障检测 故障检测时间 协同接收间隔 * 检测倍数…

【JNI】JNI环境搭建

1 前言 JNI (Java Native Interface) 是 JDK 提供的一种机制&#xff0c;用于实现 Java 代码与其他语言&#xff08;主要是 C 和 C&#xff09;编写的本地代码之间的交互。 JNI 接口详见 JDK 安装目录中的 include/jni.h 文件&#xff0c;Android NDK 对 JDK 的 JNI 进行了扩展…

利用IEEE 802.15.4z-IR UWB系统进行手势检测

本文介绍了一种符合 IEEE 802.15.4z 标准的脉冲无线电超宽带 (IR-UWB) 手势检测雷达系统。该系统可检测车辆乘客座椅上的人员是否执行了 12 个预定义手势中的某一个。这些预定义手势包括各种手部动作&#xff0c;例如左右滑动或顺时针旋转手掌。为了进行手势检测&#xff0c;我…

STM标准库-GPIO输入

文章目录 一、GPIO输入按键简介传感器模块简介硬件电路 二、C语言C语言数据类型C语言宏定义C语言typedefC语言结构体C语言枚举 三、练习3.1按键控制LED3.1.1接线图3.1.2代码效果&#xff1a; 3.2光敏电阻控制蜂鸣器3.2.1接线图3.2.2代码效果&#xff1a; 一、GPIO输入 STM32 的…

HackMyVM-Jabita

信息搜集 主机发现 ┌──(kali㉿kali)-[~] └─$ nmap -sn 192.168.43.0/24 Starting Nmap 7.95 ( https://nmap.org ) at 2025-06-01 05:20 EDT Nmap scan report for 192.168.43.1 Host is up (0.020s latency). MAC Address: C6:45:66:05:91:88 (Unknown) Nmap scan repo…

桑托斯0-1博塔弗戈 内马尔染红 阿图尔制胜球

北京时间6月2日,巴西足球甲级联赛第11轮,桑托斯主场对阵博塔弗戈。比赛中,桑托斯的内马尔因累计两张黄牌被罚出场。博塔弗戈凭借雅伊尔-库尼亚的助攻,由阿图尔打入制胜一球,最终以1-0战胜桑托斯。比赛开始前,双方队长进行了挑边仪式。第5分钟,内马尔在禁区内投诉被对手拉…

英国军事战略转向全面“备战”

△英国首相府(资料图)当地时间6月1日,总台记者从英国首相府获得信息,英国政府将在2日发布新一轮《战略国防评估报告》的同时,宣布大幅扩建其核动力攻击型潜艇舰队,并加速推进军工产业现代化。此举被外界普遍解读为英国在地缘安全压力加剧背景下,全面进入“备战状态”。新…

Java虚拟机内存区域划分

Java虚拟机内存区域划分 Java虚拟机&#xff08;JVM&#xff09;的内存区域划分主要分为五个部分&#xff1a; 程序计数器&#xff1a;程序计数寄存器&#xff0c;给CPU使用本地方法栈&#xff1a;为JVM使用到的Native方法服务方法区&#xff1a;存储的是编译后的.class文件堆…

cursor升级至0.505,运行统计视频中的人数

帮助--检查更新&#xff0c;升级。 升级后&#xff0c;新建文本&#xff0c;另存选python格式保存后&#xff0c;右下角提示选择编译器&#xff0c;选择python后&#xff0c;自动安装ms python 3.11.9 一.查看pthon安装在哪&#xff0c; winr,输入cmd后, ctrlshiftenter三个…

《Pytorch深度学习实践》ch2-梯度下降算法

------B站《刘二大人》 1.Gradient Decent 局部最优&#xff0c;全局最优&#xff0c;非凸函数&#xff1a; 梯度下降算法公式&#xff1a; 2.Implementation import matplotlib.pyplot as plt# 数据集 x_data [1.0, 2.0, 3.0] y_data [2.0, 4.0, 6.0]# 权重 w 1.0# 模型…

LabVIEW多按键自动化检测系统

LabVIEW开发一套高精度按键力与行程自动化检测系统&#xff0c;针对传统检测设备自动化程度低、定位误差大等痛点&#xff0c;实现多按键产品的全流程自动化测试。系统集成 6 轴工业机器人、高精度传感器及实时数据处理模块&#xff0c;满足汽车电子、消费电子等领域对按键手感…

Chorme如何对于youtube视频进行画中画背景播放?

画中画可以让你小窗播放&#xff0c;然后浏览器放后台还可以做点别的事情。 B站直接可以选择小窗播放&#xff0c;游览器最小化就可以&#xff0c;但是youtube的小窗播放游览器一切换就不显示了。 其实是因为youtube的小窗播放不是真的小窗播放。要想真的实现需要在youtube视…

JDBC连不上mysql:Unable to load authentication plugin ‘caching_sha2_password‘.

最近为一个spring-boot项目下了mysql-9.3.0&#xff0c;结果因为mysql版本太新一直报错连不上。 错误如下&#xff1a; 2025-06-01 16:19:43.516 ERROR 22088 --- [http-nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispat…