原来这才是Spring Boot使用AOP的正确姿势

一、为什么需要面向切面编程?面向对象编程(OOP)的好处是显而易见的,缺点也同样明显 。当需要为多个不具有继承关系的对象添加一个公共的方法的时候,例如日志记录、性能监控等,如果采用面向对象编程的方法,需要在每个对象里面都添加相同的方法,这样就产生了较大的重复工作量和大量的重复代码,不利于维护 。面向切面编程(AOP)是面向对象编程的补充,简单来说就是统一处理某一“切面”的问题的编程思想 。如果使用AOP的方式进行日志的记录和处理,所有的日志代码都集中于一处,不需要再每个方法里面都去添加,极大减少了重复代码 。
二、Spring AOP术语

原来这才是Spring Boot使用AOP的正确姿势

文章插图
 
通知(Advice)包含了需要用于多个应用对象的横切行为,完全听不懂,没关系,通俗一点说就是定义了“什么时候”和“做什么” 。
连接点(Join Point)是程序执行过程中能够应用通知的所有点 。
切点(Poincut)是定义了在“什么地方”进行切入,哪些连接点会得到通知 。显然,切点一定是连接点 。
切面(Aspect)是通知和切点的结合 。通知和切点共同定义了切面的全部内容——是什么,何时,何地完成功能 。
引入(Introduction)允许我们向现有的类中添加新方法或者属性 。
织入(Weaving)是把切面应用到目标对象并创建新的代理对象的过程,分为编译期织入、类加载期织入和运行期织入 。
三、Spring Boot AOP实战3.1 引入依赖Spring Boot使用AOP需要添加spring-boot-starter-aop依赖,如下:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>不需要再添加aspectjweaver的依赖了,因为spring-boot-starter-aop包含了aspectjweaver,并且版本是较新的版本,如果再添加老版本(如1.5.4)启动会报错 。
原来这才是Spring Boot使用AOP的正确姿势

文章插图
 
3.2 编写用于拦截的bean直接定义一个controller,代码如下:
@RestControllerpublic class AopController {@RequestMApping("/hello")public String sayHello(){System.out.println("hello");return "hello";}}3.3 定义切面Spring采用@AspectJ注解对POJO进行标注,该注解表明该类不仅仅是一个POJO,还是一个切面 。切面是切点和通知的结合,那么定义一个切面就需要编写切点和通知 。在代码中,只需要添加@Aspect注解即可 。
3.3.1 定义切点切点是通过@Pointcut注解和切点表达式定义的 。
@Pointcut注解可以在一个切面内定义可重用的切点 。
由于Spring切面粒度最小是达到方法级别,而execution表达式可以用于明确指定方法返回类型,类名,方法名和参数名等与方法相关的部件,并且实际中,大部分需要使用AOP的业务场景也只需要达到方法级别即可,因而execution表达式的使用是最为广泛的 。如图是execution表达式的语法:
execution表示在方法执行的时候触发 。以“


    推荐阅读