【徒手搭建SSM开发环境四】集成Spring(中)——集成SpringAOP

本文详细介绍了如何集成Spring AOP,包括添加相关依赖、创建AOP相关类、配置XML和注解、实现环绕通知、异常处理等。通过单元测试验证了XML与注解方式AOP的执行顺序,探讨了代理对象的生成机制,并展示了强制使用cglib代理的配置方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

集成SpringAOP

1,添加SpringAOP相关的依赖

在这里插入图片描述

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.1.12.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.9</version>
</dependency>

上述依赖中 aspectjweaver 为SpringAOP的依赖

2,刷新依赖,并检查artifact,具体操作查看《【徒手搭建SSM开发环境三】集成Spring(上)——集成SpringIOC》4-5部分内容,此处不再截图演示

3,在com.ssm.demo包下创建common代码包,此包下用于存放项目公用的类

在这里插入图片描述

4,在com.ssm.demo.common包下创建advice包,用于存放公用的AOP相关的代码

在这里插入图片描述

5,在com.ssm.demo.common.advice包下,新建两个类:ControllersExecutionAdvice和ServiceExecutionAdvice,并都实现MethodInterceptor接口,这两个类分别用于对controller和service的方法添加横切逻辑代码

在这里插入图片描述
在这里插入图片描述

6 在 ControllersExecutionAdvice类和ServiceExecutionAdvice类的invoke方法中加入环绕通知横切逻辑,使用形参invocation的proceed()实现对原方法的调用

在这里插入图片描述

在这里插入图片描述

7,在applicationContext.xml引入AOP所需要的标签定义文件

在这里插入图片描述

8,在applicationContext.xml对ControllersExecutionAdvice和ServiceExecutionAdvice这两个通知类进行注入,并且对其切面进行注册

在这里插入图片描述

9,在单元测试类SpringTest中创建单元测试方法SpringAOPTest,并在方法中添加代码,首先加载Spring配置文件,并据此文件创建Spring容器上下文对象,然后获取ProductController对象,最后调用ProductController对象的方法

在这里插入图片描述

10,运行单元测试类SpringTest的SpringAOPTest方法,如果ControllersExecutionAdvice和ServiceExecutionAdvice两个类中的环绕通知方法的打印语句都可正常执行,则表明SpringAOP集成成功

在这里插入图片描述

11,注解方式AOP测试

11.1 在com.ssm.demo.common.advice包下创建注解方式AOP切面类AnnotationExecutionAdvice,并在该类定义上添加@Component注解和@Aspect,@Component用于将该类的对象交给SpringIOC管理,@Aspect注解表明该类时一个切面定义类

在这里插入图片描述

11.2 在AnnotationExecutionAdvice类中添加切面声明方法pointcut,方法名称任意取即可,只要是public就行,同时在该方法定义上通过@Pointcut声明切面

在这里插入图片描述

11.3 在AnnotationExecutionAdvice中添加前置通知方法(切面执行前执行)before,返回通知方法(切面执行成功后执行)afterReturning,错误通知方法(切面出错时执行)afterThrowing,后置通知方法(切面执行完成后执行,不管切面是否执行成功,都会执行该方法)after,最后在这些通知方法上分别使用@Before,@AfterReturning,@AfterThrowing,@After注解与切面定义方法进行关联

在这里插入图片描述

11.4 注释掉第8步在applicationContext.xml中添加的AOP注解的配置,这里也可以不注释,注解和xml方式同时使用,但是为了调试输出的清晰可读,此处进行了注释。最后,还需要在applicationContext.xml中开启AOP注解驱动,即加入配置: <aop:aspectj-autoproxy />

在这里插入图片描述

11.5 运行单元测试类SpringTest的SpringAOPTest方法,在开发工具IDEA的控制台能够成功打印注解切面类中横切逻辑代码中的打印输出内容,则注解方式AOP调试成功

在这里插入图片描述

11.6 在ProductServiceImpl类的queryAll方法中加入异常代码后,再次执行单元测试类SpringTest的SpringAOPTest方法

在这里插入图片描述

在这里插入图片描述

从上述运行结果可以看出after通知方法不管切面是否出错都会执行,afterThrowing通知方法在切面出错时执行,afterReturning通知方法在切面成功执行后执行,并且after通知方法会在afterReturning通知方法和afterThrowing通知方法执行之前执行,猜测after通知方法是使用finally技术实现的。

11.7 在AnnotationExecutionAdvice中添加环绕通知方法around,并使用@Around注解与切面声明方法关联
在这里插入图片描述

11.8 再次执行单元测试类SpringTest的SpringAOPTest方法
在这里插入图片描述

11.9 在ProductServiceImpl类的queryAll方法中删除异常代码,同时在applicationContext.xml去掉xml方式AOP的注释,
然后在单元测试类SpringTest的SpringAOPTest方法中获取IProductService类型对象,最后执行单元测试类SpringTest的SpringAOPTest方法

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

由上述执行结果可以看出,xml方式AOP处于调用栈的最外层,而注解方式的处于调用栈的内层,同时注解方式AOP中,环绕通知方法总是先于其他通知方法执行

11.10 上述在对11.9中的执行结果的分析中,提到了调用栈的内层和外层,关于这里的内层和外层,目前猜测Spring是通过责任链模式实现的,目前还不能确定。大致推测的实现流程为:
xml方式AOP与注解方式AOP同时存在的场景下,实际上会为委托对象产生两层代理对象,即先为委托对象产生一个注解方式的AOP代理对象,再以这个注解方式AOP代理对象做为委托对象,对他产生一个xml方式AOP代理对象,这样,注解方式AOP代理对象处于整个代理链的内层,xml方式AOP代理对象就处于代理链的外层,这种在代理对象上继续产生代理对象的开发方式就是责任链模式。(此处结论等研究过源代码之后再进行补充和纠正)

11.11 在11.10中提到了代理对象,此处主要对代理对象做一下解释和调试,在SpringAOP中,产生代理对象的方式由两种,一种是JDK提供的动态代理,这种情况下要求委托对象的类要实现接口,另外一种方式是借助第三方工具cglib提供的方法增强对象实现的,这种情况下不需要委托对象的类实现接口,SpringAOP在实现过程中会依据实际情况自动选择合适的方式生成代理对象。在演示项目中,ProductController类未实现接口,而ProductServiceImpl类实现了IProductService,下边调试分别从SpringIOC容器中获取ProductController对象和ProductServiceImpl对象,并通过debug模式观察获取到对象的实际类型演示此结论。

(1)在SpringTest的SpringAOPTest方法中获取ProductController对象,并添加断点后运行单元测试方法

在这里插入图片描述

在这里插入图片描述

从执行结果能看出,此时获取到的是使用cglib技术获取到的ProductController对象的方法增强对象

(2)在SpringTest的SpringAOPTest方法中获取IProductService类型的对象,并添加断点后运行单元测试方法

在这里插入图片描述

在这里插入图片描述

从运行结果来看,测试使用的是jdk提供的动态代理方式产生的代理对象

11.12 如果项目中需要强制统一使用cglib技术实现代理对象的获取,则需要在spring配置文件applicationContext.xml中的AOP注解驱动配置上加入属性配置 proxy-target-class=“true”

在这里插入图片描述
在这里插入图片描述

有以上运行结果看出,当加入proxy-target-class="true"配置后,从SpingIOC容器中获取到的IProductService对象是通过cglib技术生成的代理对象

至此,SpringAOP集成及调试完成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值