spring-aop入门

news/2024/7/5 7:08:34

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

1、AOP介绍

AOP 即 Aspect Oriented Program 面向切面编程 ,首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能。 
所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务 
所谓的周边功能,比如性能统计,日志,事务管理等等 
周边功能在Spring的面向切面编程AOP思想里,即被定义为切面 
在面向切面编程AOP的思想里面,核心业务功能和切面功能分别独立进行开发 
然后把切面功能和核心业务功能 "编织" 在一起,这就叫AOP。

一个方法的执行,会有方法执行前、方法执行后、方法出现异常后、方法返回结果 这几个阶段,AOP的思想就是在这些阶段里动态的切入一段逻辑代码。这种思想可以把业务逻辑里的一些通用的代码抽取出来,打印日志、事务的提交和回滚、监测方法的执行时间等这些通用代码就可以与业务逻辑代码解耦。

 

2、spring使用aop

引入依赖

<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.0.6.RELEASE</version>
</dependency>

 

定义一个业务逻辑类(BussinessSevice),在业务逻辑运行的时候将日志进行打印(方法之前、方法运行结束、方法出现异常)

public class BussinessSevice {public int doBussiness(int a,int b){System.out.println("做业务处理");int result = a + b;return result;}
}

定义一个日志切面类(LogAspects)

@Aspect注解标明该类是一个切面类

@Pointcut 定义了给spring容器中的那些实例bean的那些方法给切入打印日志代码。
切面类里需要定义一些通知方法,标识了doBussiness方法的哪个阶段去切入打印日志代码。
        前置通知(@Before):logStart:在目标方法(doBussiness)运行之前运行
        后置通知(@After):logEnd:在目标方法(doBussiness)运行结束之后运行(无论方法正常结束还是异常结束)
        返回通知(@AfterReturning):logReturn:在目标方法(doBussiness)正常返回之后运行
        异常通知(@AfterThrowing):logException:在目标方法(doBussiness)出现异常以后运行
        环绕通知(@Around):手动推进目标方法运行(joinPoint.procced()), 执行之前相当于前置通知, 执行之后相当于返回通知

/*** 日志切面类*/
@Aspect
public class LogAspects {//表示匹配spring容器中包名为com.suzhe.spring.basic.aop.service的所有bean实例的所有的公有方法@Pointcut("execution(public * com.suzhe.spring.basic.aop.service.*.*(..))")public void pointCut(){}/*** 方法前* @param joinPoint*/@Before("pointCut()")public void logStart(JoinPoint joinPoint){System.out.println("logStart 参数列表是:{"+Arrays.asList(joinPoint.getArgs())+"}");}/*** 方法后* @param joinPoint*/@After("pointCut()")public void logEnd(JoinPoint joinPoint){System.out.println("logEnd......");}/*** 方法返回结果后* @param joinPoint*/@AfterReturning(value="pointCut()",returning="result")public void logReturn(JoinPoint joinPoint,Object result){System.out.println("logReturn:{"+result+"}");}/*** 方法出现异常后* @param exception*/@AfterThrowing(value="pointCut()",throwing="exception")public void logException(Exception exception){System.out.println("logException:{"+exception+"}");}/*** 手工调用目标方法的执行* @param proceedingJoinPoint* @return* @throws Throwable*/@Around("pointCut()")public Object Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{System.out.println("@Arount:before...");Object obj = proceedingJoinPoint.proceed();//相当于调用了业务方法System.out.println("@Arount:after..."+obj);return obj;}}

 

将业务逻辑组件和切面类都加入到容器中,需要开启基于注解的AOP模式,给配置类加上@EnableAspectJAutoProxy注解。

注意: 在spring以后会有很多@EnableXXXX, 表示开启某项功能, 取代XML配置

@EnableAspectJAutoProxy
@Configuration
public class AopConfig {//业务逻辑类加入容器中@Beanpublic BussinessSevice bussinessSevice(){return new BussinessSevice();}//切面类加入到容器中@Beanpublic LogAspects logAspects(){return new LogAspects();}
}

测试代码

@Test
public void test01(){AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(AopConfig.class);BussinessSevice b = app.getBean(BussinessSevice.class);int result = b.doBussiness(1,2);System.out.println(result);app.close();
}

运行后

bfaf127a00087b003ba1c8d5396e97f0e39.jpg

从上面的执行结果可以看出aop各个通知方法的执行顺序

f07338ab2f2a630b6ad3982efcce67fcefd.jpg

 

异常情况测试

定义一个业务类,该类执行方法时会抛出异常

public class BussinessExceptionSevice {public int doBussiness(int a,int b){System.out.println("doBussiness ...");int result = a + b;int i = 1/0;return result;}
}

将该类注册到spring容器中

@Bean
public BussinessExceptionSevice bussinessExceptionSevice(){return new BussinessExceptionSevice();
}

执行测试

@Test
public void test02(){AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(AopConfig.class);BussinessExceptionSevice b = app.getBean(BussinessExceptionSevice.class);int result = b.doBussiness(1,2);System.out.println(result);app.close();
}

5f73c37befb2a0bb20f7e81cb41dba23d36.jpg

从测试结果可以看出,异常情况下aop通知方法的执行顺序如下

5ae84848d2590e5dc2c9c1aa3b7a23e4a26.jpg

 

 

 

转载于:https://my.oschina.net/suzheworld/blog/3008868


http://lihuaxi.xjx100.cn/news/268477.html

相关文章

Python创建目录文件夹

Python创建目录文件夹 Python对文件的操作还算是方便的&#xff0c;只需要包含os模块进来&#xff0c;使用相关函数即可实现目录的创建。 主要涉及到三个函数 1、os.path.exists(path) 判断一个目录是否存在 2、os.makedirs(path) 多层创建目录 3、os.mkdir(path) 创建目录…

【android】java.lang.NoClassDefFoundError或classnotfount等异常错误

在android上开发&#xff0c;当导入一个外部的包&#xff0c;可能会出现这类错误&#xff0c;我已经两次碰到了&#xff0c;一次是用科大讯飞的android开发包&#xff0c;另一次是用Jsoup包&#xff08;html 解析&#xff09;。 解决方案&#xff1a; 先去掉加入的外部包 不要把…

qq音乐 android pad版,QQ音乐HD(com.tencent.qqmusicpad) - 4.12.1.4 - 应用 - 酷安

权限信息 com.tencent.qqmusicpad.permission.MMOAUTH_CALLBACK com.tencent.qqmusicpad.permission.MM_MESSAGE com.tencent.qqmusicpad.permission.sendBroadcastPromission 修改系统设置 防止手机休眠 完全的网络访问权限 读取手机状态和身份 查看WLAN连接 查看网络连接 com…

修复阻止程序安装或删除的问题

win10修复阻止程序安装或删除的问题 https://support.microsoft.com/zh-cn/help/17588/fix-problems-that-block-programs-from-being-installed-or-removed

Qt 在Label上面绘制罗盘

自己写的一个小小的电子罗盘的一个小程序&#xff0c;不过是项目的一部分&#xff0c;只可以贴绘制部分代码 效果如下图 首先开始自己写的时候&#xff0c;虽然知道Qt 的坐标系是从左上角开始的&#xff0c;所以&#xff0c;使用了算法&#xff0c;在绘制后&#xff0c;在移动回…

Facebook 万字长文:AI 模型全部迁移至 PyTorch 框架

点击上方“视学算法”&#xff0c;选择加"星标"或“置顶”重磅干货&#xff0c;第一时间送达转自 | 新智元来源 | Facebook AI Blog编辑 | LQ、yaxin2017年&#xff0c;PyTorch诞生&#xff0c;成为当下最流行的深度学习框架。近日&#xff0c;Facebook宣布让PyTorch…

梯度下降到底是什么?

点击上方“小白学视觉”&#xff0c;选择加"星标"或“置顶”重磅干货&#xff0c;第一时间送达我们回忆深度学习“三板斧”&#xff1a;1. 选择神经网络2. 定义神经网络的好坏3. 选择最好的参数集合其中步骤三&#xff0c;如何选择神经网络的好坏呢&#xff1f;梯度下…

GPT-3 的到来,程序员会被 AI 取代吗?

无需任何训练&#xff0c;AI可用任何语言编程。作者 | Frederik Bussler译者 | 弯月&#xff0c;责编 | 晋兆雨头图 | CSDN 下载自东方 IC来源 | CSDN以下为译文&#xff1a;2017年的时候&#xff0c;曾有研究人员问&#xff1a;到2040年人工智能是否承担起大多数的编程工作&am…