前言

本文主要举几个工作中典型AOP的实操案例,还有经常出现的问题(切不进去,ctrl+左键跳不到被切方法中)等等。

本文对于AOP的实现原理概不讨论,百度一搜有的是。

AOP的使用背景和好处

比如A模块是公司的核心模块,这块代码未经允许不得轻易篡改。

但是你又有新的需求,需要在公司的核心模块的某个方法上进行增强(比如在执行核心方法的之前打印自定义日志,或者修改该核心方法的入参和返回值等等)

这样你就可以在不修改核心模块源码的情况下,对源代码的方法进行增强,扩展原来方法的一些功能。

这样既能保证源代码不被破坏,又可以扩展源代码现有的功能。

一、几种使用姿势

1、@AfterReturning和@Before

@AfterReturning是后置方法,在目标方法执行后执行,@Before是前置方法,在目标方法执行前执行

它们一般配合JoinPoint来使用(不能配合ProceedingJoinPoint,会报错)。直接看例子:

被切的方法:

@Service
public class OriFuncImpl implements OriFunc{@Overridepublic String ori(String str){System.out.println("执行了原方法");return str;}
}

使用@AfterReturning 和 @Before:

@Aspect
@Component
public class AopFunc {@Pointcut("execution(* com.daji.aop_test.OriFuncImpl.ori(..))")public void test() {}@Before("test()")public void before(JoinPoint joinPoint) {Object[] args = joinPoint.getArgs();    //获取方法入参System.out.println("原方法的入参是:"+args[0]);System.out.println("原方法执行前会先执行我!!");}@AfterReturning("test()")public void after(JoinPoint joinPoint) {Object[] args = joinPoint.getArgs();    //获取方法入参System.out.println("原方法执行后会执行我!!");}}

如果遇到异常,则不执行。

当连接点方法成功执行后,返回通知方法才会执行,如果连接点方法出现异常,则返回通知方法不执行。返回通知方法在目标方法执行成功后才会执行,所以,返回通知方法可以拿到目标方法(连接点方法)执行后的结果。

@AfterReturning获取被切方法返回值,篡改返回参数:
在注解中增加returning参数即可: returning = “methodResult”

@Pointcut("execution(* com.daji.aop_test.AopTestController.test1(..))")public void publish() {}@AfterReturning(value = "publish()",returning = "methodResult")public Object afterReturningPublish(JoinPoint joinPoint, Object methodResult) {//获取方法返回值String returnJson = JSONObject.toJSONString(methodResult);Object[] args = joinPoint.getArgs();System.out.println("原方法执行后会执行我!!");//这个返回值可以被我们篡改。return methodResult;}

2、@Around

@Around是环绕通知,既可以控制入参,还可以控制原方法的执行和返回值

常常配合ProceedingJoinPoint来使用。直接看例子:

被切的方法:

@Service
public class OriFuncImpl implements OriFunc{@Overridepublic String ori(String str){System.out.println("执行了原方法");return str;}
}

使用@Around:

@Aspect
@Component
public class AopFunc {@Pointcut("execution(* com.daji.aop_test.OriFuncImpl.ori(..))")public void modifyReturn() {}@Around("modifyReturn()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {Object[] args = joinPoint.getArgs();Object result = joinPoint.proceed(args);return result;}}

3、@Around可以篡改返回值,篡改入参

需要ProceedingJoinPoint的配合

注意一定要将@Around修饰的方法用Object修饰其返回值,并且返回原方法执行的结果,如下图所示:


篡改入参一样的道理,只需要篡改下图中的 args数组,然后让其传入proceed中,即可完成篡改入参。如下图所示:

所以,这个@Around比较万能,尤其是配合ProceedingJoinPoint的使用。使AOP能做的事情更多了。

引申一下JoinPoint 和 ProceedingJoinPoint的关系:

  • ProceedingJoinPoint 只能在@Around中使用

  • JoinPoint也可以获取入参(getArgs()),它可以用于@Before 和 @AfterReturning

  • Proceedingjoinpoint 继承了 JoinPoint 。是在JoinPoint的基础上暴露出 proceed 这个方法。它们之间的关系如下图:

4、@Around如果不执行proceed(),那么原方法将不会执行

二、使用AOP常见的问题和bug

1、切不进去

检查是否有如下注解:

<dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.9.4</version>
</dependency>
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.2</version>
</dependency>

检查完毕后检查切面类,看看有没有以下注解:

2、ctrl+鼠标左键不能自动跳到被切方法:

正常情况如图:


如果你存在上述问题,检查你有没有安装下列插件:


如果你是idea社区版,那么默认是没有的,你要么自己下,要么换成正式版。

Spring AOP之@Around,@AfterReturning使用、切不进去问题解决相关推荐

  1. 一步一步手绘Spring AOP运行时序图(Spring AOP 源码分析)

    相关内容: 架构师系列内容:架构师学习笔记(持续更新) 一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程) 一步一步手绘Spring IOC运行时序图二(基于XM ...

  2. spring aop 执行顺序(@Before @Around @After @AfterReturning @AfterThrowing)

    spring aop 执行顺序(@Before @Around @After @AfterReturning @AfterThrowing) 思路 通过单元测试,调用指定方法,验证切面方法执行顺序 代 ...

  3. Spring AOP面向切面源码解析

    IoC 和 AOP 被称为 Spring 两大基础模块 AOP(Aspect-Oriented Programming) 在程序设计领域拥有其不可替代的适用场景和地位.Spring AOP 作为 AO ...

  4. Spring Aop的应用

    2019独角兽企业重金招聘Python工程师标准>>> AOP的基本概念 连接点( Jointpoint) : 表示需要在程序中插入横切关注点的扩展点,连接点可能是类初始化.方法执行 ...

  5. Spring学习总结(4)——Spring AOP教程

    2019独角兽企业重金招聘Python工程师标准>>> 一.概念 AOP(Aspect Oriented Programming):面向切面编程. 面向切面编程(也叫面向方面编程), ...

  6. Spring AOP小记

    Spring AOP vs AspectJ 本文对于学习没什么参考性,写的也比较杂乱,是在学习过程中的一个笔记,有地方可能还串不起来,个人在学习时的一些关键点记录. AOP keywords Aspe ...

  7. 彻底理解Spring AOP

    目录 前言 1. AOP概念 2. AOP的实现 3. Spring的IoC理解: 4. Sping知识整理 前言 AOP英文名为Aspect Oriented Programming,意为面向切面编 ...

  8. spring --AOP

    在说AOP之前,先来看看切片面包,我们是把面包看成一个对象,而如果想在面包中间夹点番茄酱或者其他什么东西怎么办呢,是不是需要把面包切片,在每一片都要夹点东西,在编程中给对象重复性 执行某一动作是不是特 ...

  9. Spring AOP通知实例 – Advice

    Spring AOP(面向方面编程)框架,用于在模块化方面的横切关注点.简单得说,它只是一个拦截器拦截一些过程,例如,当一个方法执行,Spring AOP 可以劫持一个执行的方法,在方法执行之前或之后 ...

最新文章

  1. 如何重装Citrix XenServer不丢失SR数据
  2. linux服务器开发板,linuxnfs服务器的建立,虚拟机、开发板间的通信
  3. SpringCloudStream整合rabbitMq
  4. 【线程】——线程的启动和中断
  5. MyBatis学习(一):简单的运行
  6. Linux内核--网络栈实现分析(一)--网络栈初始化
  7. 全角半角字符转换函数[SJIS_SBC_TO_DBC][SJIS_DBC_TO_SBC]
  8. Redis内存碎片处理
  9. AD7705/TM7705使用注意事项
  10. Linux傲腾内存,傲腾内存价格流出:每GB最低35元,最高容量512GB
  11. 山东大学人机交互技术复习纲要
  12. Android简易Flash播放器
  13. HBase数据模型与整体架构
  14. python解一元二次方程
  15. 017循环的方式定义数组、018循环for each、019方法练习、020实参和形参、021方法的返回值
  16. 你的人生是先装石头还是装沙子?
  17. 使用Amazon免费云主机和Docker,快速搭建PPTP服务器!
  18. 音视频OSD——修改叠加信息的位置
  19. html------个人简历表
  20. Swiper插件读后感

热门文章

  1. 没有微信和QQ,用记事本也能在线聊天
  2. 游戏开发入门 二、游戏中的设计模式
  3. 对UART、RS232、485通信的理解
  4. 这几个Python数据可视化探索实例,拿走不谢!
  5. Android 10开启调试模式
  6. Pytorch 并行训练(DP, DDP)的原理和应用
  7. java 雷达图_Android雷达图(蜘蛛网图),自定义view之雷达图,正五边雷达图,分数图...
  8. Input的常用属性
  9. Windows xp sp3简体中文正式版下载地址
  10. CSS中background与background-image的区别