天天看点

面向切面编程--Spring AOP

前言

学习JAVA刚开始都会接触到OOP(封装 继承 多态),这些概念将对象公共的行为抽离出来,使代码变得简洁易维护。但如果要将不同的对象引入一个公共的行为时,OOP就比较无能为力了。比较典型的就是项目中的日志功能,这个功能散布于各个不同的对象的每个层次中(执行前,执行后,异常),如果在每个需要日志功能的地方都添加一个,将会出现大量冗余的代码,且这些代码本身和业务并无太大联系,也使得业务更难理解,甚至还要加上更多处理才能让这块代码不影响到核心业务的执行。这时就引入了AOP的概念,它将不同对象的不同层次定义为切面,AOP也是面向切面编程,将核心业务行为和公共通用行为分离开,这就是它的目的。

需要加入的功能,比如上面提到的日志。

项目执行中允许你通知的地方。

切入点是在连接点的基础上定义的,比如一个类中有10个连接点,你只想通知其中5个,那这5个连接点你就可以定义为切入点。

切入点和通知的结合,切入点表示“在什么地方做”,通知表示“做什么”和“什么时候做”,两个结合表明“在什么时候什么地方做什么”,这就是一个完整的切面定义。

向现有的类添加方法属性。就是将切面在目标类中使用。

将切面引入目标对象创建一个新的代理类的过程。

文章示例使用JDK1.8+SpringBoot框架进行讲解。小伙伴们要有一定的SpringBoot使用经验。

1.aop

2.junit

正文

在目标方法执行前织入增强处理。

下面的这段就是在测试代码执行前获得请求的参数和IP地址,并打印日志。

执行后,控制台打印:

可以看到,在每个方法执行前,都打印了一条日志,这就是前置增强。

在目标方法执行后织入增强处理。

这里有两个注解需要注意以下,@After和@AfterReturning,@AfterReturning如果方法异常或其他原因中断了,是通知不到的,@After是任何情况都能通知得到。我们这里用@AfterReturning。

后置增强可以拿到方法返回值,所以我们在日志输出里增加了个返回值,运行效果如下:

后置增强相对于前置增强的位置变了,前置增强是在目标方法执行前,而后置增强是在目标方法执行后,并且可以获得返回值。

在目标方法执行前后织入增强处理。

环绕增强从名字就可以看出,可以针对目标方法前后都进行增强处理。

举个栗子,我们要在方法执行前日志打印参数,方法执行后打印返回值,就可以这么写:

结果如下:

不知道大家有没有注意到,环绕增强的入参由JoinPoint变成了ProceedingJoinPoint,点进去可以看到ProceedingJoinPoint继承了JoinPoint并且在原本的接口上暴露了proceed()方法。这个方法就是让目标方法执行,这样才能支持环绕通知。

结尾

上面主要讲到了前置增强,后置增强和环绕增强这三种常用的,还有其他的比如异常增强等其他增强下篇文章再讨论。如果发现错误或者我理解错了的地方,欢迎大家及时指正。

继续阅读