AOP 的核心概念
- 切面(Aspect):通常是一个类,在里面可以定义切入点和通知。
- 连接点(Joint Point):被拦截到的点,因为 Spring 只支持方法类型的连接点,所以在 Spring 中连接点指的就是被拦截的到的方法,实际上连接点还可以是字段或者构造器。
- 切入点(Pointcut):对连接点进行拦截的定义。
- 通知(Advice):拦截到连接点之后所要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类。
- AOP 代理:AOP 框架创建的对象,代理就是目标对象的加强。Spring 中的 AOP 代理可以使 JDK 动态代理,也可以是 CGLIB 代理,前者基于接口,后者基于子类。
Spring 默认使用 JDK 动态代理,在需要代理类而不是代理接口的时候,Spring 会自动切换为使用 CGLIB 代理。
Spring AOP 相关注解
- @Aspect: 将一个 java 类定义为切面类。
- @Pointcut:定义一个切入点,可以是一个规则表达式,比如下例中某个 package 下的所有函数,也可以是一个注解等。
- @Before:在切入点开始处切入内容。
- @After:在切入点结尾处切入内容。
- @AfterReturning:在切入点 return 内容之后切入内容(可以用来对处理返回值做一些加工处理)。
- @Around:在切入点前后切入内容,并自己控制何时执行切入点自身的内容。
- @AfterThrowing:用来处理当切入内容部分抛出异常之后的处理逻辑。
其中 @Before、@After、@AfterReturning、@Around、@AfterThrowing 都属于通知。
AOP 顺序问题
@Order(i) 注解来标识切面的优先级, i 的值越小,优先级越高。
假设现在我们一共有两个切面,一个 WebLogAspect,我们为其设置 @Order(100);而另外一个切面 DistributeLockAspect 设置为 @Order(99),所以 DistributeLockAspect 有更高的优先级,这个时候执行顺序是这样的:在 @Before 中优先执行 @Order(99) 的内容,再执行 @Order(100) 的内容。而在 @After 和 @AfterReturning 中则优先执行 @Order(100) 的内容,再执行 @Order(99) 的内容,可以理解为先进后出的原则。
AOP依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
https://www.ibm.com/developerworks/cn/java/j-spring-boot-aop-web-log-processing-and-distributed-locking/index.html