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

SpringAOP的介绍和入门

目录

1.SpringAOP概述

1.1SpringAOP的概念

1.2 AOP的优势

2.Spring的AOP技术-配置文件方式

2.1 AOP相关的术语

2.2 AOP配置文件方式的入门

1.导入依赖

2.业务层模拟保存账户

3.配置切面类

4.配置文件配置

5.编写测试代码

2.3 切入点的表达式

2.4 AOP的通知类型

1.前置通知

2.最终通知

3.后置通知

4.异常通知

5.环绕通知


1.SpringAOP概述

1.1SpringAOP的概念

什么是AOP的技术?
在软件业,AOP为AspectOrientedProgramming的缩写,意为:面向切面编程,AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构

AOP最早由AOP联盟的组织提出的,制定了一套规范.Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范
SpringAOP是通过预编译方式或者运行期动态代理实现程序功能的统一维护的一种技术
AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型
利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率
AOP:面向切面编程.(思想.---解决OOP遇到一些问题)
AOP 采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)
为什么要学习AOP?可以在不修改源代码的前提下,对程序进行增强!!

1.2 AOP的优势

JDK 的动态代理技术

1、为接口创建代理类的字节码文件

2、使用ClassLoader 将字节码文件加载到JVM

3、创建代理类实例对象,执行对象的目标方法 cglib 代理技术

2.Spring的AOP技术-配置文件方式

2.1 AOP相关的术语

Joinpoint(连接点) 所谓连接点是指那些被拦截到的点。在spring中,这些点指的 是方法,因为spring只支持方法类型的连接点

Pointcut(切入点)-- 所谓切入点是指我们要对哪些Joinpoint进行拦截的定义

Advice(通知/增强)-- 所谓通知是指拦截到Joinpoint之后所要做的事情就是通知. 通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)

Target(目标对象)-- 代理的目标对象

Weaving(织入)-- 是指把增强应用到目标对象来创建新的代理对象的过程

Proxy(代理)--一个类被AOP织入增强后,就产生一个结果代理类

Aspect(切面)--是切入点和通知的结合,以后咱们自己来编写和配置的

2.2 AOP配置文件方式的入门

1.导入依赖

<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.3</version> </dependency> </dependencies>

2.业务层模拟保存账户

package com.qcby.service.impl; import com.qcby.service.UserService; public class UserServiceImpl implements UserService { @Override public void save() { System.out.println("业务层:保存用户......."); } } package com.qcby.service; public interface UserService { void save(); }

3.配置切面类

package com.qcby.aspect; public class MyXmlAspect { /** * 通知 * 自定义切面类=切入点(表达式)+通知(增强的代码) */ public void log(){ //发送手机短信 //发送邮件/记录日志/事务管理 System.out.println("增强的代码执行了......"); } }

4.配置文件配置

配置文件:

<?xml version="1.0" encoding="UTF-8"?> <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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> </beans>

(1)配置bean对象,把对象交给Spring管理

<bean id="userService" class="com.qcby.service.impl.UserServiceImpl"/> <!--定义切面类--> <bean id="myXmlAspect" class="com.qcby.aspect.MyXmlAspect"/>

(2)切面类的配置

<!--配置AOP的增强--> <aop:config> <aop:aspect ref="myXmlAspect"> <!--前置通知:在UserServiceImpl的save方法执行之前会增强--> <aop:before method="log" pointcut="execution(public void com.qcby.service.impl.UserServiceImpl.save())"/> </aop:aspect> </aop:config>

5.编写测试代码

import com.qcby.service.UserService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class Demo { @Autowired private UserService userService; /** * 测试 */ @Test public void run1(){ userService.save(); } }

测试:

2.3 切入点的表达式

在xml文件配置切入点的时候,需要定义表达式:

表达式格式如下:

execution([权限修饰符] 返回值类型 包名.类名.方法名(参数))

权限修饰符可以省略

返回值类型不能省略,要根据方法来编写返回值。可以用*代替

包名就是要增强的方法所在的包位置,拿

com.qcby.service.impl.UserServiceImpl.save()

举例:

com不能省略,可以用*代替

中间的包名可以用*省略,也可以使用..

类名也可以用*代替,例如*ServiceImpl

方法也可以用*代替

参数如果是一个参数可以用*代替,任意参数用..代替

把配置文件中的表达式换成这样也可以:

<aop:before method="log" pointcut="execution(void *.qcby..*Impl.save(..))"/>

2.4 AOP的通知类型

1.前置通知

目标方法执行前,进行增强。

前置通知在入门中写过,不再赘述

2.最终通知

目标方法执行成功或者失败,进行增强。

配置:

<!--最终通知:不论UserServiceImpl的save方法执行成功或者失败都会增强--> <aop:after method="log" pointcut="execution(public void com.qcby.service.impl.UserServiceImpl.save())"/>

我们可以在save方法中模拟异常:

package com.qcby.service.impl; import com.qcby.service.UserService; public class UserServiceImpl implements UserService { @Override public void save() { //模拟异常 int a=1/0; System.out.println("业务层:保存用户......."); } }

测试方法不变,运行:

3.后置通知

目标方法执行成功后,进行增强。

配置:

<!--后置通知:在save方法执行成功之后增强--> <aop:after-returning method="log" pointcut="execution(public void com.qcby.service.impl.UserServiceImpl.save())"/>

测试:增强方法的执行在后面

4.异常通知

目标方法执行失败后,进行增强。

<!-- 异常通知 在遇到异常时进行增强--> <aop:after-throwing method="log" pointcut="execution(public void com.qcby.service.impl.UserServiceImpl.save())"/>

还是模拟异常:

把异常去掉:

5.环绕通知

目标方法执行前后,都可以进行增强。目标对象的方法需要手动执行。

配置环绕通知方法:

1.必须接收一个 ProceedingJoinPoint 参数(或 JoinPoint,但通常用 ProceedingJoinPoint,因为它可以控制目标方法的执行)。

2.必须调用 proceed() 方法来执行目标方法。

3.通常返回一个 Object 类型(如果目标方法有返回值的话,需要返回它)。

/** * 环绕通知方法 */ public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("环绕通知:目标方法执行前"); // 执行目标方法 Object result = joinPoint.proceed(); System.out.println("环绕通知:目标方法执行后"); return result; }

配置:

<!--环绕通知 在目标方法执行前后,都可以进行增强。目标对象的方法需要手动执行。--> <aop:around method="logAround" pointcut="execution(public void com.qcby.service.impl.UserServiceImpl.save())"/>

执行:

http://www.cnnetsun.cn/news/64679.html

相关文章:

  • AutoGPT镜像适用于科研场景吗?高校团队已投入使用
  • GitHub热门项目推荐:基于Qwen3-14B开发的企业级AI助手
  • 从零到网络安全专家:一张全景路线图(2025版)
  • LeetCode 46/51 排列型回溯题笔记-全排列 / N 皇后
  • 一周回顾:勒索飙升、AI上阵、人形机器人被盯上
  • 嵌入式FOTA进阶:文件系统直接升级+串口分段传输深度指南!
  • AutoGPT提示词工程技巧:提升任务拆解准确性
  • Stable Diffusion AIGC 视觉设计实战教程之 07-图生图
  • 当毕业论文不再是“一个人的深夜战场”:一位研究生眼中的AI科研协作者如何重塑写作流程
  • 统计提交svn代码行数,文件以及文档
  • 解锁学术新次元:书匠策AI科研工具为毕业论文注入智慧动能
  • GPT-5.2全面解析:AI“打工能力“大提升,程序员职场必备技能
  • vue-springboot基于Java医院药品管理系统的设计与实现_8z88u88g
  • 深圳 CNC 加工哪家强?慧闻智造!精密零件加工的靠谱专家
  • Java中高级面试题详解(十五):彻底搞懂 Spring Boot 启动流程与扩展点,别再只会写 main 方法!
  • CTF 解题核心思维 + 新手入门全攻略
  • 2026PCB产业高端化浪潮与慕尼黑上海电子展的连接枢纽
  • 揭秘Web组件的隐形守护者:影子DOM如何彻底改变前端开发格局!
  • AI基于Springboot的图书馆在线占座系统_s58324g1
  • 从零构建Agent:大模型智能代理的六步落地指南!
  • 股票历史分时BOLL数据之Python、Java等多种主流语言实例代码演示通过股票数据接口获取数据
  • 25 岁转行不迷茫!网安工程师手把手带学,入门到精通
  • springboot个人任务管理系统-计算机毕业设计源码63521
  • 别瞎学了!2025 网安工程师入门全流程,零基础也能会,收藏即上岸
  • 把AI大模型想象成一个“超级猜词游戏”!非专业也能看懂的工作原理,原来这么简单!
  • 企业级智能体终极指南!从定义到落地,一篇彻底解决你的所有疑问!
  • AI大乱斗!当GPT-5.2遇上Claude-4.5-opus,谁会先“认怂”?史上最硬核模型PK赛!
  • 如何实现员工网站管控?这六款软件来帮您管理员工
  • 护网蓝队初级岗位薪资真相:从 0 学网安,小白参与护网也能日入 2000+
  • 【商城系统】