详解Spring的AOP切面编程

本文详细介绍了如何在Spring环境中使用AOP(面向切面编程)实现代码增强,包括XML配置和Java注解方式,并重点讲解了环绕通知的运用和通知传参。作者还讨论了如何在实际项目中管理和配置切面和通知对象。
摘要由CSDN通过智能技术生成

说了那么多,还是上代码最简单直接。准备工作:

① 测试依赖的包及其版本(注:很多教程中都提到需要 aopalliance包,但是博主测试过程中并没有确认此包存在的必要性)

aspectjweaver-1.9.2.jar

commons-logging-1.2.jar

spring-aop-4.3.18.RELEASE.jar

spring-beans-4.3.18.RELEASE.jar

spring-context-4.3.18.RELEASE.jar

spring-core-4.3.18.RELEASE.jar

spring-expression-4.3.18.RELEASE.jar

spring-test-4.3.18.RELEASE.jar

② 定义两个基础模型类(如下),业务是:给只有打电话功能的手机动态的添加 拍照、玩游戏这样的非主业务功能

//主业务功能

public class HuaWeiPhone {

public void ring() {

System.out.println(“华为手机,产销第一”);

}

}

//额外添加的功能

public class Photograph {

public void takePictures(){

System.out.println(“华为手机,拍照牛批”);

}

public void playGames(){

System.out.println(“华为手机,游戏玩得也这么畅快”);

}

}

1、XML配置的方式


根据以上Java代码,进行非常简单的配置,就能看到动态的为手机增加了拍照功能的效果了——

aop:config

<aop:pointcut id=“ring” expression=“execution(* main.model.HuaWeiPhone.ring(…))”/>

<aop:aspect ref=“photograph”>

<aop:before method=“takePictures” pointcut-ref=“ring”/>

<aop:after method=“playGames” pointcut-ref=“ring”/>

</aop:aspect>

</aop:config>

在Spring环境下测试类XML配置——

@RunWith(SpringJUnit4Cla***unner.class)

@ContextConfiguration(locations = “classpath:main/resource/applicationContext.xml”)

public class SpringTest {

@Autowired

HuaWeiPhone huaWeiPhone;

@Test

public void testXml(){

huaWeiPhone.ring();

}

}

输出结果

详解Spring的AOP切面编程

2、Java注解的方式


需要先说明的是,Spring的基于注解的 AOP 实际上是借鉴吸收了AspectJ的功能,所以你会看到很多类似 AspectJ 框架的注解。在之前的模型类上通过添加相应的注解改造成一个切面——

@Aspect //将该类标注为一个AOP切面

@Component

public class Photograph {

@Pointcut(“execution(* main.model.HuaWeiPhone.ring(…))”)

public void chenbenbuyi (){

}

@Before(“chenbenbuyi()”)

public void takePictures(){

System.out.println(“华为手机,拍照牛批”);

}

@After(“chenbenbuyi()”)

public void playGames(){

System.out.println(“华为手机,游戏玩得也这么畅快”);

}

}

同样的,目标类(HuaWeiPhone)上也要添加@Componet注解将其交给Spring 容器管理。然后,如果是纯注解的话,还要一个配置类——

//配置注解扫描

@ComponentScan(basePackages = “main”)

//启用AspectJ的自动代理功能

@EnableAspectJAutoProxy

public class JavaConfig {

}

最后,在Spring的环境下测试——

@RunWith(SpringJUnit4Cla***unner.class)

//@ContextConfiguration(locations = “classpath:main/resource/applicationContext.xml”)

@ContextConfiguration(classes = JavaConfig.class)

public class SpringTest {

@Autowired

HuaWeiPhone huaWeiPhone;

@Test

public void testAnno(){

huaWeiPhone.ring();

}

}

结果同上,这里就不展示了。不过需要注意的是,不管什么配置方式,基于Spring 的AOP编程实现的前提都是要将通知对象和被通知方法交给Spring IOC容器管理,也就是要声明为Spring 容器中的Bean。

四、需求升级

======

在第三部分中,博主只是展示了最最简单的AOP功能实现,还有稍微复杂的技能点没有列出。比如,5种通知类型中的环绕通知呢?再比如,我的切面代码如果要传参数怎么办呢?接下来博主依次讲解。

① 关于环绕通知的运用

基于 二 中的阐述,5 种通知类型中 环绕通知 是功能最为强大,实际上,我们可以在环绕通知中个性化的定制出前置 、后置、异常和返回的通知类型,而如果单独的采用前置、后置等通知类型,如果业务涉及多线程对成员变量的修改,可能出现并发问题,所以环绕要比单独的使用另外的几种通知类型更加的安全。我们对上面的切面基于环绕通知进行修改,使之包含所有的通知类型的功能——

@Aspect

@Component

public class Photograph {

@Pointcut(“execution(* main.model.HuaWeiPhone.ring(…))”)

public void chenbenbuyi (){

}

@Around(“chenbenbuyi()”)

public void surround(ProceedingJoinPoint joinPoint){

try {

System.out.println(“目标方法执行前执行,我就是前置通知”);

joinPoint.proceed();

// ①

// int i =1/0; // ② 制造异常

System.out.println(“正常返回,我就是返回通知”);

}

catch (Throwable e) {

System.out.println(“出异常了,我就是异常通知”);

}

finally {

System.out.println(“后置通知,我就是最终要执行的通知”);

}

}

}

XML的配置和上面的其它通知类型一样,只不过元素标签为 <aop:around />而已。上面的打印语句的位置就对应了其它几种通知类型执行切面逻辑的时机。这里注意,环绕通知方法体中需要有 ProceedingJoinPoint 接口作为参数,在环绕通知中,通过执行该参数的 proceed() 方法来调用通知需要切入的目标方法。如果不执行 ① 处的调用,被通知方法实际上会被阻塞掉,所以你会看到,明明测试中执行了被通知的方法,实际却没有执行。该参数对象还可以获取方法签名、代理对象、目标对象等信息,可以自己测试着玩。

② 关于通知的传参问题

切面虽然是通用逻辑,但实际在切入不同的目标方的时候,可能还是希望通知方法根据被通知方法的不同(比如参数不同)而执行不一样的逻辑,这就要求我们的通知也能获取到被通知方法传入的参数。通过切点表达式,这也很容易办到。首先我们修改被通知的方法可以传参:

public void ring(String str) {

System.out.println(“华为手机,产销第一”);

int i =1/0;

}

然后切面中切点表达式和切面方法也做对应的修改——

@Aspect

@Component

public class Photograph {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后希望可以帮助到大家!

千千万万要记得:多刷题!!多刷题!!

之前算法是我的硬伤,后面硬啃了好长一段时间才补回来,算法才是程序员的灵魂!!!!

篇幅有限,以下只能截图分享部分的资源!!

(1)多线程(这里以多线程为代表,其实整理了一本JAVA核心架构笔记集)

image

(2)刷的算法题(还有左神的算法笔记)

image

(3)面经+真题解析+对应的相关笔记(很全面)

image

(4)视频学习(部分)

ps:当你觉得学不进或者累了的时候,视频是个不错的选择

在这里,最后只一句话:祝大家offer拿到手软!!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
多线程为代表,其实整理了一本JAVA核心架构笔记集)

[外链图片转存中…(img-YB5Fq47t-1712993579074)]

(2)刷的算法题(还有左神的算法笔记)

[外链图片转存中…(img-TQZQiqyV-1712993579075)]

(3)面经+真题解析+对应的相关笔记(很全面)

[外链图片转存中…(img-ADU4XCI2-1712993579075)]

(4)视频学习(部分)

ps:当你觉得学不进或者累了的时候,视频是个不错的选择

在这里,最后只一句话:祝大家offer拿到手软!!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 11
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值