从今天开始,阅读spring framework官方文档中的spring aop部分,并将要点记录如下:
-
spring的面向切面编程
- spring提供两种方式来编写自定义切面:基于XML配置方式、基于@Aspect注解方式
-
AOP概念
- Aspect: 在spring aop中,切面(aspects)就是普通的类通过xml配置或者使用@Aspect注解实现的。
- Join Point:代表方法执行。
- Advice:包含5中类型:
- Before advice:通知(advice)在连接点之前执行。
- After returning advice:通知在连接点正常完成之后执行。(比如:方法正常返回,未抛出异常)。
- After throwing advice:通知在方法抛出异常时执行。
- After (finally) advice:不管连接点返回正常还是异常,通知都会在返回后执行。
- Around advice:通知环绕在连接点周围。这个是最强的通知,它可以在方法执行前后自定义行为。它也会选择是否继续执行连接点或直接返回自己的返回值或抛出异常来结束执行。
-
通过切入点匹配的连接点的概念是AOP的关键。
-
spring aop的能力与目标
- spring aop 目前只支持方法执行连接点。
- spring框架的一个重要理念是非侵入性。所以spring可以无缝整合spring aop、ioc 容器、aspectj。
-
aop 代理
-
spring aop默认使用标准JDK动态代理作为AOP代理,这样可以使任何一个接口(或接口集)被代理。spring aop也可以使用CGLIB代理,这对代理类是必须的,但对接口不是。默认情况下,如果一个业务类没有实现接口,就会使用CGLIB。但是在程序中使用接口而不使用类是更好的体现。
-
-
支持@AspectJ
-
启用@AspectJ支持
- 启用@AspectJ支持可通过XML方式或者java方式配置。无论使用哪种方式,都要先保证AspectJ的aspectjweaver.jar在classpath中。
-
java配置方式
@Configuration @EnableAspectJAutoProxy public class AppConfig { }
-
xml配置方式
<aop:aspectj-autoproxy/>
-
声明一个切面
package org.xyz; import org.aspectj.lang.annotation.Aspect; @Aspect public class NotVeryUsefulAspect { }
- 在classpath中,@Aspect注解不能让spring自动检测到切面类作为普通类注入。要实现这个目的,需要增加注解@Component。
- 在spring aop中,一个切面本身不能作为其他切面的通知目标。@Aspect注解,表明这个类是一个切面,而且该类不能被自动代理。
-
声明一个切点(Pointcut)
- 一个切点定义包含两部分:
- 签名:在注解方式中,签名通过普通的方法定义来实现,并且方法必须是void返回类型。
- 切点表达式:表明我们感兴趣的是哪个方法。使用@Pointcut注解。
- 下面的例子表示:一个名叫 anyOldTransfer 的切点匹配任何名字为transfer的方法执行
@Pointcut("execution(* transfer(..))") // the pointcut expression private void anyOldTransfer() {} // the pointcut signature
- 一个切点定义包含两部分:
-