Spring framework Day19:Spring AOP xml配置示例二

news2025/7/21 13:13:38

一、开始学习

1、新建项目,结构如下

2、添加 spring 依赖
 
    <!-- spring 的核心依赖 -->
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.23</version>
        </dependency>
 
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.4.5</version>
        </dependency>

         <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.8</version>
        </dependency>
 
 
    </dependencies>

AspectJ 是 eclipse 开源组织编写的一套强大的 AOP 框架, 它拥有特殊的编译器和类加载器,因此可以在编译时创建 代理和类加载时创建代理,但由于 spring 本身对 AOP 的实现是基于运行时创建代理的,所以只能使用 jdk 和 cglib 来创建代理,但 spring 却使用了 AspectJ 的切入点表达式 以及相关的注解,使用起来更加的简单和方便 。

使用AspectJ,你可以通过定义切面来在不修改原始代码的情况下,将通用功能织入到应用程序中。

3、在 service 包下新建一个 UserService 类 
@Slf4j
public class UserService {

    public void add(){
        log.info("添加用户...");
    }

}
4、在 aspect 包下新建一个 ServiceAspect 切面类
/**
 * @Date 2023-10-12
 * @Author qiu
 * 这是一个切面类
 */
@Slf4j
public class ServiceAspect implements MethodBeforeAdvice, AfterReturningAdvice, MethodInterceptor, ThrowsAdvice {

    /**
     * 环绕通知
     *
     * @param invocation 回调处理器,用于调用目标对象的方法
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        log.info("环绕通知前...");
        // 调用目标对象方法
        Object proceed = invocation.proceed();
        log.info("环绕通知后....");
        return proceed;
    }

    /**
     * 后置通知
     *
     * @param returnValue 目标方法的返回值
     * @param method      目标对象的方法
     * @param args        目标方法所需要的参数
     * @param target      目标对象
     * @throws Throwable
     */
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        log.info("后置通知...");
    }

    /**
     * 前置通知
     *
     * @param method 准备调用的目标对象
     * @param args   目标方法的所需要的参数
     * @param target 目标对象(被代理的对象)
     * @throws Throwable 有可能抛出的异常
     */
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        log.info("前置通知...");
    }

    /**
     * 异常通知,根据官方文档说明
     * 该方法名必须叫做 afterThrowing
     * 并且必须包含一个 Exception 参数
     *
     * @param e
     */
    public void afterThrowing(Exception e) {
        log.info("异常通知...." + e.getMessage());
    }
}

这是一个使用AspectJ实现的切面类示例。该切面类实现了MethodBeforeAdviceAfterReturningAdviceMethodInterceptorThrowsAdvice这几个接口。

其中:

  1. invoke()方法是环绕通知,在目标方法执行前后进行拦截,并在前后打印日志。
  2. afterReturning()方法是后置通知,在目标方法正常返回后执行,并打印日志。
  3. before()方法是前置通知,在目标方法执行前执行,并打印日志。
  4. afterThrowing()方法是异常通知,在目标方法抛出异常时执行,并打印异常信息。

通过使用这些切面通知,你可以在应用程序中将这些关注点逻辑切入到目标方法的执行过程中,实现更灵活和可维护的代码结构。

5、在 resources 包下新建一个 beans.xml 文件
<?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: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/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 装配 UserService(目标对象)    -->
    <bean id="userService" class="edu.nf.ch19.service.UserService"/>

    <!-- 装切面,将切面纳入 spring 容器中管理    -->
    <bean id="serviceAspect" class="edu.nf.ch19.aspect.ServiceAspect"/>

    <!-- Aop 配置 proxy-target-class="true" 属性设置为 true
         表示强制使用 cglib 生成代理,无论目标对象有没有实现接口
       -->
    <aop:config proxy-target-class="true">
        <!-- 配置切入点,spring 使用了 AspectJ 的切入点表达式
             来实现了 AOP 中切入点的概念,通过切入点表达式
             可以找到需要增强的目标方法。而找到的这些目标方法就称之为
             连接点。id 属性指定一个切入点的唯一标识,
             expression 用于声明切入点表达式。
             切入点表达式的语法:
             execution(访问修饰符 包名.类名.方法名(参数类型))
             也可以使用通配符来扩大切入点的范围
             execution(访问修饰符 包名.*.*(..))
         -->
        <aop:pointcut id="myPointcut" expression="execution(* edu.nf.ch19.service.UserService.*(..))"/>
        <!-- 配置通知器(也就是切面),使用 advice-ref 属性引用上面装配的切面
             pointcut-ref 引用切入点的 id
         -->
        <aop:advisor advice-ref="serviceAspect" pointcut-ref="myPointcut"/>
    </aop:config>

</beans>

 这是一个使用Spring AOP配置的XML示例。该配置文件定义了一个userService的目标对象和一个serviceAspect的切面对象,并通过AOP将切面应用到目标对象的方法上。

解析该配置文件的主要内容如下:

  1. 配置了userService的目标对象。通过指定class属性为edu.nf.ch19.service.UserService,将该类装配为 Spring 容器中的一个 bean。

  2. 配置了serviceAspect的切面对象。通过指定class属性为edu.nf.ch19.aspect.ServiceAspect,将该类装配为 Spring 容器中的一个 bean。

  3. <aop:config> 标签内配置了 AOP 相关的内容。通过设置proxy-target-class属性为true,启用了基于类的代理。

  4. 定义了 myPointcut 切点,使用表达式execution(* edu.nf.ch19.service.UserService.*(..))来匹配 edu.nf.ch19.service.UserService 类中的所有方法。

  5. 定义了 advisor,将serviceAspect作为通知(advice-ref)应用到 myPointcut 切点(pointcut-ref)。

通过这样的配置,你可以实现在edu.nf.ch19.service.UserService类的所有方法上应用serviceAspect切面对象中定义的通知逻辑。

6、测试
public class Main {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserService service = context.getBean(UserService.class);
        service.add();
    }

}

运行结果

7、看图分析

1)什么是连接点?

目标对象的方法(被切入的方法)就称之为连接点,一个切入点可以对应目标对象的的多个连接点。AOP是对一个类的方法在不进行任何修改的前提下进行增强,那么UserService 里的 add()方法,就是连接点。

2)什么是通知?

通知(也叫增强)就是对目标行为植入额外的逻辑代码,从而增强原有的功能。切面类(通知类)里面的所有方法都是增强方法。

3)什么是切入点?

执行 add() 方法的时候本来是只有添加用户,但是执行后输出了环绕通知、前置通知、后置通知,也就是说,add()方法已经被增强了,被增强的方法就叫做切入点。

4)什么是切面?

切面是用于编写切面逻辑的一个类,这个类很类似于JDK动态代理中的回调处理器或者cglib中的方法拦截器,主要就是将需要增强目标对象的功能代码编写在这个类中,而这些功能增强的代码就是切面逻辑。 通知是增强的方法,会有多个,切入点是需要增强的方法,也会有多个,哪个切入点需要添加哪个通知,它们之间的关系就叫做切面。

5)什么是切面类(通知类)?

通知(增强)是一个方法,方法不能独立存在需要写在类中,这个类就叫切面类(通知类)。

 6)什么是代理?
AOP 是在不改变原有设计 ( 代码 ) 的前提下对其进行增强的,它的底层采用的是代理模式实现
的,所以要对原始对象进行增强,就需要对原始对象创建代理对象,在代理对象中的方法把通知
[ :UserService 中的 add 方法 ] 内容加进去,就实现了增强 , 这就是我们所说的代理 (Proxy)

 在运行时动态创建的对象,称之为代理对象,负责调用目标对象的方法,并执行增强功能。

 7)  什么是目标?

被代理的对象就是目标对象。

目标对象就是要被增强的类(UserService)。

8)什么是织入?

将切面中的增强逻辑应用到目标具体的连接点上并产生代理的过程称之为织入。

切面类中的增强方法应用到 UserService 的 add() 方法中的这个过程就是织入。

因此通常描述为“将通知织入到具体的目标”。

织入的时机可以分为以下几种:

  1. 类加载时织入,需要特殊的类加载器(LTW)

  2. 编译时织入,需要特殊的编译器(CTW)

  3. 运行时织入,通常使用JDK或者CGLIB在程序运行创建代理对象,

    spring就是基于运行时织入的。(注意:spring仅仅只是用到了AspectJ的切入点表达式和注解,但并没有使用AspectJ的类加载和编译时织入功能,而是使用JDK和CGLIB在运行时生成代理对象。)

 二、使用 AspectJ 的好处?

使用 AspectJ 有以下几个好处:

  1. 更强大的切面编程能力:AspectJ 提供了更丰富、更灵活的切面编程功能,可以针对更细粒度的 Join Point(连接点)进行切面编程。它支持更多的切点表达式,可以在方法的入参、返回值、异常等多个层面进行切面逻辑的定义,使得切面的编写更加灵活和精确。

  2. 更高效的性能:AspectJ 不依赖动态代理机制,使用字节码增强技术,生成修改后的目标类字节码,将切面逻辑直接插入到目标类的指定位置。这种静态织入方式比运行时的动态代理织入更高效,减少了额外的代理调用开销,提升了系统的运行性能。

  3. 更广泛的应用场景:AspectJ 可以与 Spring AOP 进行无缝集成,可以作为 Spring 框架的一部分使用。除了在 Spring 应用中使用外,AspectJ 还可以用于 JavaEE 应用、独立的 Java 应用,甚至能够修改第三方类库的字节码,具备更广泛的应用场景。

  4. 更丰富的功能扩展:AspectJ 提供了一些特殊的切面类型,例如 percflowpertarget 等,可以实现更复杂的切面逻辑。此外,AspectJ 还提供了一些高级功能,如异常处理、事务管理等,可以扩展切面的应用范围,使得切面编程更加强大和灵活。

总的来说,使用 AspectJ 可以提供更强大、更灵活的切面编程能力,同时具备更高的性能效率和更广泛的应用场景,是一个优秀的切面编程框架。

三、总结

本章节多了很多个理论知识点,连接点、通知、切入点、切面、代理、目标、织入,这本个理论很重要,也是 AOP 切面编程的最重要的知识,要想学好 AOP 就要理解它的思想,把这八个理解了就差不多了。

四、gitee 案例

案例完整地址:https://gitee.com/qiu-feng1/spring-framework.git

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

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

相关文章

2023,简历石沉大海?软件测试岗位真的已经饱和了....

各大互联网公司的接连裁员&#xff0c;政策限制的行业接连消失&#xff0c;让今年的求职雪上加霜&#xff0c;想躺平却没有资本&#xff0c;还有人说软件测试岗位饱和了&#xff0c;对此很多求职者深信不疑&#xff0c;因为投出去的简历回复的越来越少了。 另一面企业招人真的…

Redis数据结构之ziplist

前言 Redis 为了提高内存效率&#xff0c;设计了一种特殊的数据结构 ziplist&#xff08;压缩列表&#xff09;。ziplist 本质是一段字节数组&#xff0c;采用了一种紧凑的、连续存储的格式&#xff0c;可以有效地压缩数据&#xff0c;提高内存效率。 hash、zset 在数据量比较…

CSS 基础知识-01

CSS 基础知识 1.CSS概述2. CSS引入方式3. 选择器4.文字控制属性5. 复合选择器6. CSS 特性7.背景属性8.显示模式9.选择器10.盒子模型 1.CSS概述 2. CSS引入方式 3. 选择器 4.文字控制属性 5. 复合选择器 6. CSS 特性 7.背景属性 8.显示模式 9.选择器 <!DOCTYPE html> <…

AutoGPT:自动化GPT原理及应用实践

一、AutoGPT介绍 想象一下&#xff0c;生活在这样一个世界里&#xff0c;你有一个人工智能助手&#xff0c;它不仅能够理解你的需求&#xff0c;而且还能够与你一起学习与成长。人工智能已无缝融入我们工作、生活&#xff0c;并帮助我们有效完成各种目标。大模型技术的发展与应…

【数据分享】2022年我国30米分辨率的地形粗糙度(起伏度)数据(免费获取)

地形数据&#xff0c;也叫DEM数据&#xff0c;是我们在各项研究中最常使用的数据之一。之前我们分享过2022年哥白尼30米分辨率的DEM数据&#xff0c;该数据被公认为是全球最佳的开源DEM数据之一&#xff0c;甚至没有之一&#xff08;可查看之前的文章获悉详情&#xff09;&…

Jmeter的性能测试

性能测试的概念 定义&#xff1a;软件的性能是软件的一种非功能特性&#xff0c;它关注的不是软件是否能够完成特定的功能&#xff0c;而是在完成该功能时展示出来的及时性。 由定义可知性能关注的是软件的非功能特性&#xff0c;所以一般来说性能测试介入的时机是在功能测试…

particles 粒子背景插件在vue3中的使用

particles 粒子背景插件在vue3中的使用 概述使用完整代码概述 npm 链接 https://www.npmjs.com/package/particles.vue3 GitHub地址 https://github.com/tsparticles/vue3 配置参数说明: color: String类型 默认’#dedede’。粒子颜色。particleOpacity: Number类型 默认0.7。…

【Linux】线程互斥与同步

文章目录 一.Linux线程互斥1.进程线程间的互斥相关背景概念2互斥量mutex3.互斥量的接口4.互斥量实现原理探究 二.可重入VS线程安全1.概念2.常见的线程不安全的情况3.常见的线程安全的情况4.常见的不可重入的情况5.常见的可重入的情况6.可重入与线程安全联系7.可重入与线程安全区…

【halcon】halcon轮廓总结之select_contours_xld

前言 select_contours_xld 我认为是一个非常常用且实用的算子&#xff0c;用于对轮廓进行筛选。 简介 这段文档描述了一个名为"SelectContoursXld"的操作&#xff0c;用于根据不同特征选择XLD&#xff08;XLD是一种图像数据表示形式&#xff0c;表示轮廓线&#x…

使用 Bard 的 Google Hotel 插件查询酒店

使用 Bard 的 Google Hotel 插件&#xff0c;您可以通过以下步骤找到符合您需求的酒店&#xff1a; 在 Google 搜索中打开 Bard 插件。输入您要搜索的城市或酒店名称。选择您要搜索的日期和入住人数。选择您要搜索的酒店类型和价格范围。单击“搜索”按钮。 Find hotels for a…

OpenCV实战完美实现眨眼疲劳检测!!

目录 1&#xff0c;项目流程 2&#xff0c;代码实现 3&#xff0c;结果展示 应用场景主要是在监控系统和驾驶员安全监测中&#xff1a; 监控系统&#xff1a;可以将该项目应用于监控摄像头的视频流中&#xff0c;实时检测闭眼行为。通过实时计算闭眼次数和眼睛长宽比&#x…

ubuntu20.04安装FTP服务

安装 sudo apt-get install vsftpd# 设置开机启动并启动ftp服务 systemctl enable vsftpd systemctl start vsftpd#查看其运行状态 systemctl status vsftpd #重启服务 systemctl restart vsftpdftp用户 sudo useradd -d /home/ftp/ftptest -m ftptest sudo passwd ftptest…

数字签名 及 数字证书 原理笔记

这里是对 数字签名 及 数字证书 原理该视频做的一个笔记&#xff0c;链接 前言 如果对一些加密算法不懂可以参考这篇文章 数字签名 小明发送文件给小红时对文件做出签名 将文件进行hash算法加密得到hash值&#xff0c;并且对该hash值使用私钥进行加密&#xff08;私钥加密的…

接口加密解决方案:Python的各种加密实现!

01、前言 在现代软件开发中&#xff0c;接口测试已经成为了不可或缺的一部分。随着互联网的普及&#xff0c;越来越多的应用程序都采用了接口作为数据传输的方式。接口测试的目的是确保接口的正确性、稳定性和安全性&#xff0c;从而保障系统的正常运行。 在接口测试中&…

【python海洋专题二十三】共用坐标轴

点击蓝字,关注我们 共用坐标轴上期画出subplot 但是坐标轴觉得多余 本期内容 优化坐标轴 1:未优化 优化 关键语句 # % 不显示坐标刻度 plt.xticks([])往期推荐 图片 【python海洋专题一】查看数据nc文件的属性并输出属性到txt文件 【python海洋专题二】读取水…

关于 Invalid bound statement (not found): 错误的解决

关于 Invalid bound statement not found: 错误的解决 前言错误原因解决方法1. 检查SQL映射文件2. 检查MyBatis配置3. 检查SQL语句4. 检查命名约定5. 清除缓存6. 启用日志记录 重点注意 结语 我是将军我一直都在&#xff0c;。&#xff01; 前言 当开发Java Spring Boot应用程…

手把手教你随机合并全部视频添加同一个文案的方法

今天&#xff0c;我将为你介绍一个简单易行的方法&#xff0c;只需两个步骤&#xff0c;让你轻松实现批量合并视频。 1. 在浏览器中搜索并下载“固乔智剪软件”&#xff0c;然后打开软件。这款软件是一款专业的视频剪辑工具&#xff0c;它提供了多种视频剪辑功能&#xff0c;包…

OpenCV模板匹配实现银行卡数字识别

目录 1&#xff0c;项目流程 2&#xff0c;代码流程解读 2.1 导入工具包 2.2 设置参数 2.3 指定信用卡类型 2.4 展示图像 ​编辑 2.5 读取一个模板图像 2.6 转化为灰度图--------->再转化为二值图像 2.7 计算轮廓 ​编辑 2.8 导入我们要识别的图像&…

设计海报都有哪些好用的软件推荐

在新媒体时代&#xff0c;设计在各个方面都是不可分割的。它最初是设计师的工作&#xff0c;并逐渐成为新媒体编辑的必要技能。 网页内容需要图片和文字&#xff0c;应用程序需要独特的风格基调&#xff0c;人们更喜欢分享视频和图片&#xff0c;而不是简单的文本。因此&#…

HTX 与 Zebec Protocol 深度合作,并将以质押者的身份参与 ZBC Staking

自 2023 年下半年以来&#xff0c;加密市场始终处于低迷的状态&#xff0c;在刚刚结束的 9 月&#xff0c;加密行业总融资额创下 2021 年以来的新低&#xff0c;同时在 DeFi 领域 DEX 交易额为 318.9 亿美元&#xff0c;同样创下 2021 年 1 月以来的新低。 对于投资者而言&…