AOP 概述
1. 什么是 AOP?
AOP 是一种设计思维,在不批改源代码的状况下给程序动静对立增加额定性能的一种技术,如图:
2.AOP 利用原理剖析
AOP 底层基于代理机制 (动静形式) 实现性能扩大:
1):如果指标对象 (被代理对象) 实现接口,则底层能够采纳 JDK 动静代理机制为指标对象创立代理对象(指标类和代理类会实现独特接口)。
2):如果指标对象 (被代理对象) 没有实现接口,则底层能够采纳 CGLIB 代理机制为指标对象创立代理对象(默认创立的代理类会继承指标对象类型)。
如图:
AOP 默认应用 CGLIB 代理,如需应用 JDK 代理配置文件配置:
spring.aop.proxy-target-class=false
基于 JDK 代理形式实现:
基于 CGLIB 代理形式实现:
AOP 相干术语:
切面(aspect):个别为一个具体类(@Aspect 注解正文)切入点()
告诉(Advice):在切面的某个特定点上执行的扩大
切入点 (pointcut): 应用 @Pointcut 注解进行切入点的形容,应用 bean 表达式定义切入点, 语法:bean(spring 容器中治理的某个 bean 的名字),bean 表达式是一种粗粒度的切入点表达式(不能具体到 bean 中哪个办法) 需写一个办法作为承载切入点
连接点(joinpoint):封装了切入点汇合办法中的某个正在执行的指标办法
AOP 增加的依赖:
<dependency> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
注解阐明:
- @Aspect 注解用于标识或者形容 AOP 中的切面类型,基于切面类型构建的对象用于为指标对象进行性能扩大或控制目标对象的执行。
- @Pointcut 注解用于形容切面中的办法,并定义切面中的切入点(基于特定表达式的形式进行形容),在本案例中切入点表达式用的是 bean 表达式,这个表达式以 bean 结尾,bean 括号中的内容为一个 spring 治理的某个 bean 对象的名字。
- @Around 注解用于形容切面中办法,这样的办法会被认为是一个盘绕告诉(外围业务办法执行之前和之后要执行的一个动作),@Aournd 注解外部 value 属性的值为一个切入点表达式或者是切入点表达式的一个援用(这个援用为一个 @PointCut 注解形容的办法的办法名)。
- ProceedingJoinPoint 类为一个连接点类型,此类型的对象用于封装要执行的指标方
告诉类型(告诉 -Advice 形容的是一种扩大业务):
1.@Before。(指标办法执行之前执行)
2.@AfterReturning。(指标办法胜利完结时执行)
3.@AfterThrowing。(指标办法异样完结时执行)
4.@After。(指标办法完结时执行)
5.@Around.(重点把握, 指标办法执行前后都能够做业务拓展)(优先级最高)
阐明:在切面类中应用什么告诉,由业务决定,并不是说,在切面中要把所有告诉都写上。
切入点表达式加强:
**
bean 表达式(重点)
bean 表达式个别利用于类级别,实现粗粒度的切入点定义,案例剖析:
- bean(“userServiceImpl”)指定一个 userServiceImpl 类中所有办法。
- bean(“*ServiceImpl”)指定所有后缀为 ServiceImpl 的类中所有办法。
阐明:bean 表达式外部的对象是由 spring 容器治理的一个 bean 对象, 表达式外部的名字应该是 spring 容器中某个 bean 的 name。
缺点: 不能准确到具体方法, 也不能针对于具体模块包中的办法做切入点设计
===========================================================
within 表达式(理解)
within 表达式利用于类级别,实现粗粒度的切入点表达式定义,案例剖析:
- within(“aop.service.UserServiceImpl”)指定以后包中这个类外部的所有办法。
- within(“aop.service.*”) 指定当前目录下的所有类的所有办法。
- within(“aop.service..*”) 指定当前目录以及子目录中类的所有办法。
within 表达式利用场景剖析:
1)对所有业务 bean 都要进行性能加强,然而 bean 名字又没有规定。
2)按业务模块 (不同包下的业务) 对 bean 对象进行业务性能加强。
===========================================================
execution 表达式(理解)
execution 表达式利用于办法级别,实现细粒度的切入点表达式定义,案例剖析:
语法:execution(返回值类型 包名. 类名. 办法名(参数列表))。
- execution(void aop.service.UserServiceImpl.addUser())匹配 addUser 办法。
- execution(void aop.service.PersonServiceImpl.addUser(String)) 办法参数必须为 String 的 addUser 办法。
- execution( aop.service...*(..)) 万能配置。
===========================================================
@annotation 表达式(重点)
@annotaion 表达式利用于办法级别,实现细粒度的切入点表达式定义,案例剖析
- @annotation(anno.RequiredLog) 匹配有此注解形容的办法。
- @annotation(anno.RequiredCache) 匹配有此注解形容的办法。
其中:RequiredLog 为咱们本人定义的注解, 当咱们应用 @RequiredLog 注解润饰业务层办法时, 零碎底层会在执行此办法时进行日扩大操作。
切面优先级设置实现
切面的优先级须要借助 @Order 注解进行形容,数字越小优先级越高,默认优先级比拟低。
列如:@Order(1),@Order(2)