当前位置: 首页 > news >正文

Spring-AOP

目录

一:什么是AOP

二:AOP快速入门 

2.1导入AOP坐标

2.2定义dao接口和实现类

2.3定义通知类

 2.4在配置类中进行Spring注解包扫描和开启AOP功能

2.5定义测试类测试结果 

三:AOP工作流程 

四:AOP的切入点表达式 

4.1语法格式

4.2通配符 

五:AOP通知类型 

5.1前置通知 

5.2后置通知

5.3最终通知 

5.4异常通知

5.5环绕通知

六:总结 


一:什么是AOP

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

总的来说,AOP就是一编程规范,目的是在不改变方法源代码的基础上对方法进行功能增强。

二:AOP快速入门 

2.1导入AOP坐标

在pom.xml中导入aop坐标

<dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.3.31</version></dependency>
  <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.7</version></dependency>

2.2定义dao接口和实现类

BookDao接口中: 

package com.lcyy.dao;public interface BookDao {void read();
}

实现类:注意要在BookDaoImpl方法上加入注解@Repository表示为交给Spring的一个组件

import com.lcyy.dao.BookDao;
import org.springframework.stereotype.Repository;@Repository
public class BookDaoImpl implements BookDao {@Overridepublic void read() {System.out.println("BookDao AOP 实现");}
}

2.3定义通知类

建立一个aop的包,在包下建立一个MyAdvice的通知类

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;@Component//放在普通类上,交给ioc容器管理
@Aspect//定义这个类为切面类
public class MyAdvice {//定义连接点@Pointcut("execution(void com.lcyy.dao.BookDao.read())")private void pc(){}//定义通知@Before("pc()")public void testAdvice(){System.out.println("执行前的时间毫秒值:");System.out.println(System.currentTimeMillis());}
}

 注意:

1.在MyAdvice类上要加入注解:@Aspect表示定义为一个切面类,@Component表示交给ioc容器管理。

2.@Pointcut注解要求配置在方法上方,("execution(void com.lcyy.dao.BookDao.read())")为切入点表达式,execution为关键字,

void为返回值 com.lcyy.dao.BookDao.read()为com.lcyy包下的dao包下的BookDao接口中的read()方法。

3.@Before("pc()") 其中@Before为前置通知,表示为在方法执行前执行。关于通知的几种类型,下面会详细讲解。其中 "pc()" 表示将连接点和通知捆绑起来,注意方法名必须相同。

 2.4在配置类中进行Spring注解包扫描和开启AOP功能

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration
@ComponentScan("com.lcyy")
@EnableAspectJAutoProxy//开启aop
public class SpringConfig {
}

其中注解 @EnableAspectJAutoProxy 表示开启AOP通知,交给IOC容器管理

2.5定义测试类测试结果 

import com.lcyy.config.SpringConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class BookDaoTest {public static void main(String[] args) {//获取容器ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);BookDao bookDao = ctx.getBean(BookDao.class);bookDao.read();}
}

测试结果:

三:AOP工作流程 

  1. Spring容器启动

  2. 读取所有切面配置中的切入点

  3. 初始化bean,判定bean对应的类中的方法是否匹配到任意切入点

    • 匹配失败,创建原始对象

    • 匹配成功,创建原始对象(目标对象)的代理对象

  4. 获取bean执行方法

    • 获取的bean是原始对象时,调用方法并执行,完成操作

    • 获取的bean是代理对象时,根据代理对象的运行模式运行原始方法与增强的内容,完成操作

验证AOP的代理对象,在刚才测试类中获取

import com.lcyy.config.SpringConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class BookDaoTest {public static void main(String[] args) {//获取容器ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);BookDao bookDao = ctx.getBean(BookDao.class);bookDao.read();System.out.println(bookDao.getClass());}
}

 测试结果:

其中:class com.sun.proxy.$Proxy19 就是为代理对象的类名 

四:AOP的切入点表达式 

4.1语法格式

描述方法一:执行com.lcyy.dao包下的BookDao接口中的无参数read方法

execution(void com.lcyy.dao.BookDao.read())

描述方法二:执行com.lcyy.dao包下的BookDaoImpl实现类中的无参数read方法

 execution(void com.lcyy.dao.BookDaoImpl.read())

切入点表达式标准格式:动作关键字(访问修饰符 返回值 包名.类/接口名.方法名(参数) 异常名)  

execution(public User com.itheima.service.UserService.findById(int)) 

其中:

  • 动作关键字:描述切入点的行为动作,例如execution表示执行到指定切入点

  • 访问修饰符:public,private等,可以省略

  • 返回值:写返回值类型

  • 包名:多级包使用点连接

  • 类/接口名:

  • 方法名:

  • 参数:直接写参数的类型,多个类型用逗号隔开

  • 异常名:方法定义中抛出指定异常,可以省略

4.2通配符 

(*):单个独立的任意符号,可以独立出现,也可以作为前缀或者后缀的匹配符出现

 (..):多个连续的任意符号,可以独立出现,常用于简化包名与参数的书写

常用的通配符表达式为: 

@Pointcut("execution(* com.lcyy.dao.*.*(..)")

表示任意的访问修饰符 在com.lcyy.dao包下的任意类中的所有方法(..)表示可以有形参也可以没有形参。

五:AOP通知类型 

  • AOP通知共分为5种类型

    • 前置通知:在切入点方法执行之前执行

    • 后置通知:在切入点方法执行之后执行,无论切入点方法内部是否出现异常,后置通知都会执行。

    • 环绕通知(重点):手动调用切入点方法并对其进行增强的通知方式。

    • 最终通知:在切入点方法执行之后执行,如果切入点方法内部出现异常将不会执行。

    • 异常通知:在切入点方法执行之后执行,只有当切入点方法内部出现异常之后才执行。

5.1前置通知 

  • 名称:@Before

  • 类型:==方法注解==

  • 位置:通知方法定义上方

  • 作用:设置当前通知方法与切入点之间的绑定关系,当前通知方法在原始切入点方法前运行

  • 案例代码:

 //前置通知@Before("execution(void com.lcyy.dao.BookDao.write())")public void testAdvice2(){System.out.println("我是前置通知");}

5.2后置通知

  • 名称:@AfterReturning

  • 类型:==方法注解==

  • 位置:通知方法定义上方

  • 作用:设置当前通知方法与切入点之间的绑定关系,当前通知方法在原始切入点方法后运行

  • 案例代码:

    @AfterReturning("execution(void com.lcyy.dao.BookDao.write())")public void testAdvice4(){System.out.println("我是后置通知");}

5.3最终通知 

  • 名称:@After

  • 类型:==方法注解==

  • 位置:通知方法定义上方

  • 作用:设置当前通知方法与切入点之间的绑定关系,当前通知方法在原始切入点方法后运行

  • 案例代码:

@After("execution(void com.lcyy.dao.BookDao.write())")public void testAdvice3(){System.out.println("我是最终通知");}

5.4异常通知

  • 名称:@AfterThrowing

  • 类型:==方法注解==

  • 位置:通知方法定义上方

  • 作用:设置当前通知方法与切入点之间的绑定关系,当前通知方法在原始切入点方法运行抛出异常后执行

@AfterThrowing("execution(void com.lcyy.dao.BookDao.write())")public void testAdvice5(){System.out.println("我是异常通知");}

在以上四个通知后,我们在测试类中测试以上通知

 注意:书写了异常通知,却没有执行,是因为简单的代码实现没有异常。

测试异常通知:

在BookDaoImpl 的实现类中书写测试异常的代码

@Overridepublic void write() {System.out.println("BookDao AOP 实现");int a = 10/0;System.out.println("a = " + a);}

测试结果:

5.5环绕通知

  • 名称:@Around(重点,常用)

  • 类型:==方法注解==

  • 位置:通知方法定义上方

  • 作用:设置当前通知方法与切入点之间的绑定关系,当前通知方法在原始切入点方法前后运行

  • 案例代码:

  @Around("execution(void com.lcyy.dao.BookDao.jiyi())")public Object testJiyi(ProceedingJoinPoint PJ) throws Throwable {System.out.println("我时前置通知");Object Oj = PJ.proceed();System.out.println("我是后置通知");return Oj;}

 测试结果:

注意:

  1. 环绕通知方法形参必须是ProceedingJoinPoint,表示正在执行的连接点,使用该对象的proceed()方法表示对原始对象方法进行调用,返回值为原始对象方法的返回值。

  2. 环绕通知方法的返回值建议写成Object类型,用于将原始对象方法的返回值进行返回,哪里使用代理对象就返回到哪里。

六:总结 

AOP在spring中是一个很重要的概念,理解和运用AOP在以后的业务开发中有很重要的作用!

相关文章:

Spring-AOP

目录 一&#xff1a;什么是AOP 二&#xff1a;AOP快速入门 2.1导入AOP坐标 2.2定义dao接口和实现类 2.3定义通知类 2.4在配置类中进行Spring注解包扫描和开启AOP功能 2.5定义测试类测试结果 三&#xff1a;AOP工作流程 四&#xff1a;AOP的切入点表达式 4.1语法格…...

算法程序设计-快速排序

快速排序采用---分治策略 L |------x-------------| R 第一步确定分界点&#xff1a;q[l],q[(lr)/2],q[r]随机 第二步调整范围&#xff1a;L |--------<x|>x------------| R 第三步递归处理左右两端 两种做法&#xff1a; 第一种&#xff1a;暴力解决 另外定义两个…...

Jmeter用jdbc实现对数据库的操作

我们在用Jmeter进行数据库的操作时需要用到配置组件“JDBC Connection Configuration”&#xff0c;通过配置相应的驱动能够让我们通过Jmeter实现对数据库的增删改查&#xff0c;这里我用的mysql数据库一起来看下是怎么实现的吧。 1.驱动包安装 在安装驱动之前我们要先查看当前…...

Mac 上安装多版本的 JDK 且实现 自由切换

背景 当前电脑上已经安装了 jdk8; 现在再安装 jdk17。 期望 完成 jdk17 的安装&#xff0c;并且完成 环境变量 的配置&#xff0c;实现自由切换。 前置补充知识 jdk 的安装路径 可以通过查看以下目录中的内容&#xff0c;确认当前已经安装的 jdk 版本。 cd /Library/Java/Java…...

springboot如何发送邮件,java如何发送邮件随机码作为验证

maven <dependency><groupId>com.sun.mail</groupId><artifactId>javax.mail</artifactId><version>1.6.2</version></dependency> 然后java package com.metasoft.common.utils;import java.util.Properties;import javax.…...

使用QLoRA在自定义数据集上finetuning 大模型 LLAMA3 的数据比对分析

概述: 大型语言模型(LLM)展示了先进的功能和复杂的解决方案,使自然语言处理领域发生了革命性的变化。这些模型经过广泛的文本数据集训练,在文本生成、翻译、摘要和问答等任务中表现出色。尽管LLM具有强大的功能,但它可能并不总是与特定的任务或领域保持一致。 什么是LL…...

编译和链接(超详细)

✅博客主页:爆打维c-CSDN博客​​​​​​ &#x1f43e; &#x1f539;分享c语言知识及代码 一、编译和链接实例 假设我们有一个名为main.c的C语言源文件&#xff0c;它包含了一个简单的Hello World程序。我们可以使用gcc编译器对该源文件进行编译&#xff0c;生成一个可执行…...

Rust Turbofish 的由来

0x01 什么是 Turbofish 我们运行如下 Rust Snippet&#xff1a; fn main() {let numbers: Vec<i32> vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];let even_numbers numbers.into_iter().filter(|n| n % 2 0).collect();println!("{:?}", even_numbers); }不出意…...

2.外卖点餐系统(Java项目 springboot)

目录 0.系统的受众说明 1.系统功能设计 2.系统结构设计 3.数据库设计 3.1实体ER图 3.2数据表 4.系统实现 4.1用户功能模块 4.2管理员功能模块 4.3商家功能模块 4.4用户前台功能模块 4.5骑手功能模块 5.相关说明 新鲜运行起来的项目&#xff1a;如需要源码数据库…...

Universal Thresholdizer:将多种密码学原语门限化

参考文献&#xff1a; [LS90] Lapidot D, Shamir A. Publicly verifiable non-interactive zero-knowledge proofs[C]//Advances in Cryptology-CRYPTO’90: Proceedings 10. Springer Berlin Heidelberg, 1991: 353-365.[Shoup00] Shoup V. Practical threshold signatures[C…...

【UE5学习笔记】编辑及运行界面:关闭眼部识别(自动曝光)

自动曝光&#xff0c;也就是走进一个黑暗的环境&#xff0c;画面会逐渐变量&#xff0c;以模拟人眼进入黑暗空间时瞳孔放大&#xff0c;进光量增加的一种真实视觉感受&#xff1a; 制作过程中是否关闭自动曝光&#xff0c;取决于游戏的性质&#xff0c;但是个人认为&#xff0c…...

未来科技的前沿:深入探讨人工智能的进展、机器学习技术和未来趋势

文章目录 一、人工智能的定义和概述1. 人工智能的基本概念2. 人工智能的发展历史 二、技术深入&#xff1a;机器学习、深度学习和神经网络1. 机器学习2. 深度学习3. 神经网络 三、人工智能的主要目标和功能1. 自动化和效率提升2. 决策支持和风险管理3. 个性化服务和预测未来 本…...

3-qt综合实例-贪吃蛇的游戏程序

引言&#xff1a; 如题&#xff0c;本次实践课程主要讲解贪吃蛇游戏程序。 qt贪吃蛇项目内容&#xff1a; 一、功能需求 二、界面设计 各组件使用&#xff1a; 对象名 类 说明 Widget QWidge 主窗体 btnRank QPushButton 排行榜-按钮 groupBox QGroupBox 难…...

QGraphicsView实现简易地图12『平移与偏移』

前文链接&#xff1a;QGraphicsView实现简易地图11『指定层级-定位坐标』 提供地图平移与偏移功能。地图平移是指将地图的中心点更改为给定的点&#xff0c;即移动地图到指定位置。地图偏移是指将当前视口内的地图向上/下/左/右/进行微调&#xff0c;这里偏移视口宽/高的四分之…...

深入探索 Vue 中的 createVNode 与 resolveComponent

在 Vue 开发中&#xff0c;createVNode和resolveComponent是两个至关重要的工具&#xff0c;它们为我们提供了强大的能力来灵活地创建和操控组件。 一、首先&#xff0c;让我们深入了解一下createVNode。 这是一个用于创建虚拟节点的关键函数&#xff0c;通过它&#xff0c;我…...

【记录42】centos 7.6安装nginx教程详细教程

环境&#xff1a;腾讯云centos7.6 需求&#xff1a;安装nginx-1.24.0 1. 切入home文件 cd home 2. 创建nginx文件 mkdir nginx 3. 切入nginx文件 cd nginx 4. 下载nginx安装包 wget https://nginx.org/download/nginx-1.24.0.tar.gz 5. 解压安装包 tar -zxvf nginx-1.24.0.…...

C语言程序设计(不熟悉的点)

一、switch多路分支语句 二、条件表达式 三、循环 for循环&#xff1a; for循环的三个表达式不是必须的&#xff0c;第一个表达式之前声明过&#xff0c;可以不写&#xff0c;第三个表达式可以放在循环体里面&#xff1b;第二个表达式可以不写&#xff0c;为死循环。 空循环…...

DAO是什么?有什么用途?

DAO&#xff08;Decentralized Autonomous Organization&#xff0c;去中心化自治组织&#xff09;是一种基于区块链技术的组织形式&#xff0c;它没有中央管理层&#xff0c;而是通过智能合约和区块链上的代码来运作。DAO 的决策过程是透明的&#xff0c;通常由组织的成员通过…...

Socket学习记录

本次学习Socket的编程开发&#xff0c;该技术在一些通讯软件&#xff0c;比如说微信&#xff0c;QQ等有广泛应用。 网络结构 这些都是计算机网络中的内容&#xff0c;我们在这里简单回顾一下&#xff1a; UDP(User Datagram Protocol):用户数据报协议;TCP(Transmission Contr…...

黑马 - websocket搭建在线聊天室

这里写自定义目录标题 一、消息推送常见方式二、websocket 是什么&#xff1f;三、websocket api的介绍1、客户端 &#xff08;浏览器&#xff09;2、服务端api 四、实现在线聊天室1、需求2、聊天室流程分析3、消息格式4、代码实现 一、消息推送常见方式 1、轮训方式 2、SSE…...

【每日力扣】543. 二叉树的直径与101. 对称二叉树

&#x1f525; 个人主页: 黑洞晓威 &#x1f600;你不必等到非常厉害&#xff0c;才敢开始&#xff0c;你需要开始&#xff0c;才会变的非常厉害 543. 二叉树的直径 给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的…...

【linux】——日志分析

1. 日志文件 1.1 日志文件的分类 日志文件&#xff1a; 是用于记录Linux系统中各种运行消息的文件&#xff0c;相当于Linux主机的“日记". 日志文件对于诊断和解决系统中的问题很有帮助&#xff0c;系统一旦出现问题时及时分析日志就会“有据可查”。此外。当主机遭受攻…...

【intro】GraphSAGE

论文 https://arxiv.org/pdf/1706.02216 abstract 大图中节点的低维embedding已经被证明在各种预测任务中非常有用&#xff0c;然而&#xff0c;大多数现有的方法要求在embedding训练期间图中的所有节点都存在;这些先前的方法属于直推式&#xff08;transductive&#xff09…...

管理能力学习笔记九:授权的常见误区和如何有效授权

授权的常见误区 误区一&#xff1a;随意授权 管理者在授权工作时&#xff0c;需要依据下属的能力、经验、意愿问最自己&#xff1a;这项工作适合授权给Ta做吗&#xff1f;如果没有&#xff0c;可以通过哪些方法进行培训呢&#xff1f; 误区二&#xff1a;缺乏信任 心理暗示…...

第21天 反射

反射概述 想象一下&#xff0c;你在一个房间里边&#xff0c;但你看不见自己&#xff0c;也不知道自己是谁。这时候你面前有一个镜子&#xff0c;你可以通过镜子的反射来观察自己。反射就像这面镜子。它让你能够检查、分析、修改Java中的对象、类、方法等 使用情况&#xff1…...

多链路聚合设备是什么

多链路聚合设备属于通信指挥装备。 乾元通多链路聚合设备&#xff0c;它能够将多个网络链路聚合成一个逻辑链路&#xff0c;以实现高速、稳定、可靠的数据传输。多链路聚合设备的核心技术包括链路聚合、负载均衡、故障切换等&#xff0c;能够智能管理和优化利用不同网络链路&a…...

基于springboot+vue+Mysql的自习室预订系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…...

解决后端ID传到前端时被截断,末尾显示00

问题原因&#xff1a; Java后端Long类型的取值和前端Number类型取值范围不一样。 解决方案&#xff1a; 将id字段进行json序列化时转为字符串。 JsonSerialize(using ToStringSerializer.class) private Long id;...

Transformer中的数据输入构造

文章目录 1. 文本内容2. 字典构造2.1 定义一个类用于字典构造2.2 拆分文本2.3 构造结果 3. 完整代码 1. 文本内容 假如我们有如下一段文本内容&#xff1a; Optics It is the branch of physics that studies the behaviour and properties of light . Optical Science 这段…...

完美实现vue3异步加载组件

经过几个小时的努力&#xff0c;终于实现了&#xff0c;根据组件名异常加载组件&#xff0c;直接上代码&#xff0c;网上的很多代码方都有坑&#xff0c;先贴出比较坑的代码&#xff1a; <template><view class"main"> <view class"tops"…...

如何用ps做网站首页/全国疫情最新消息

前言&#xff1a; 由于数据库设计原因&#xff0c;需要对数据进行行转列操作&#xff0c;列的情况比较多&#xff0c;不唯一&#xff0c;所以需要动态创建行转列。 环境&#xff1a; Mysql 5.7数据库 内容讲解 今天的工作主要分为两个阶段&#xff0c;首先要熟悉静态行转列操…...

颇有名气的网站建设专家/百度推广获客方法

网页中的下拉列表多数是假的下拉列表。也就是正常的控件&#xff0c;需要进行鼠标停留或点击等操作才会出现的。 当出现真的下拉列表&#xff0c;html语言必然是这种。 需要先进行导入select方法 from selenium.webdriver.support.ui import Select emwzj.find_element_by_…...

计算机网络实验 做网站的/最近的国内新闻

目录 replace if..else.. ARouter跳转形式 null 判断 过滤 map loading提示 toast调用 打印日志 when 时间控件 Glide 图片加载 防止重点 Dagger 调用 launch Dialog提示 get() 埋点 repeat循环 ActivityManager 延迟加载 runCatch 登录拦截 水纹点击效果 replace tv_nam…...

网站代码优化多少钱/西安百度推广联系方式

要进入深度学习相关的领域&#xff0c;Python是一方面&#xff0c;另一方面是本身学历问题。深度学习&#xff0c;机器学习&#xff0c;人工智能这些大火的领域&#xff0c;它们目前的进入门槛其实是学历&#xff0c;然后是能力&#xff0c;不一定非要说是名校研究生&#xff0…...

商城网站开发的任务书/广州信息流推广公司排名

http://www.springframework.net/doc-latest/reference/html/web.html转载于:https://blog.51cto.com/yerik/1076409...

温州建设网站/汽油价格最新调整最新消息

一、Dubbo介绍 1、dubbo 是什么 Dubbo是一个分布式服务框架&#xff0c;以及SOA治理方案。其功能主要包括&#xff1a;高性能NIO通讯及多协议集成&#xff0c;服务动态寻址与路由&#xff0c;软负载均衡与容错&#xff0c;依赖分析与降级等。 Dubbo是Alibaba开源的分布式服务…...