8、AOP切入点详解

时间:2021-01-23 16:48:24

@AspectJ支持

如果使用@Configuration注解配置Spring,需要添加@EnableAspectJAutoProxy

@Configuration
@EnableAspectJAutoProxy
public class ApplicationConfig {

}

如果使用XML需要在XML中添加

<aop:aspectj-autoproxy />

声明一个切面

首先需要在类中添加@Aspect注解,注意是@Aspect而不是@AspectJ。然后将这个类加入到Spring容器中就可以了。上一章的例子中有讲到。
这里使用注解或者XML配置都可以。

声明一个切入点

使用@Pointcut注解声明一个切入点。
语法:@Pointcut(the pointcut expression)
@Pointcut支持下列Pointcut标识符。
- execution - 这个是Spring中最主要的Pointcut标志符,用于指定要匹配的方法。
- within - 限定切入点所在的类。@Pointcut("within(package.class)")
- this - 用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配。方法是在那个类中被调用的。
- target - 用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;指明拦截的方法属于那个类。
- args - 限定切入点方法的参数。
- bean - 匹配Bean
- @target - 用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解;必须是在目标对象上声明这个注解,在接口上声明的对它不起作用
- @args - 用于匹配当前执行的方法传入的参数持有指定注解的执行;
- @within - 用于匹配所有持有指定注解类型的方法;必须是在目标对象上声明这个注解,在接口上声明的对它不起作用
- @annotation - 用于匹配当前执行方法持有指定注解的方法;

参考http://jinnianshilongnian.iteye.com/blog/1415606

execution表达式

语法:execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)
throws-pattern?)

modifiers-pattern:方法的类型,public,private...
ret-type-pattern:返回值类型,*表示所有,void表示没有返回值…
declaring-type-pattern:类型匹配
name-pattern:方法名匹配,*表示所有,set\*表示所有以set开头的方法
param-pattern:表示参数类型,..表示所有都匹配,*匹配有一个参数的方法,**匹配有两个参数的方法。

//所有public方法
execution(public * *(..))

//所有以set开头的方法
execution(* set*(..))

//com.xyz.service.AccountService中的所有方法
execution(* com.xyz.service.AccountService.*(..))

//com.xyz.service包下的所有类的所有方法
execution(* com.xyz.service.*.*(..))

//com.xyz.service包及其子包下的所有类的所有方法
execution(* com.xyz.service..*.*(..))

其他表达式

//com.xyz.service下所有类的所有方法
within(com.xyz.service.*)

//com.xyz.service及其子包下所有类的所有方法
within(com.xyz.service..*)

//所有实现了AccountService接口的代理对象
this(com.xyz.service.AccountService)

//所有实现了AccountService接口的目标对象
target(com.xyz.service.AccountService)

//所有蚕食是Serializable类型的方法。
args(java.io.Serializable)

注解切入点的写法

//目标对象有@Transactional注解,是在类上注解而不是方法,不支持接口
@target(org.springframework.transaction.annotation.Transactional)

//目标对象有@Transactional注解,是在类上注解而不是方法,支持接口
@within(org.springframework.transaction.annotation.Transactional)

//有@Transactional注解的所有方法
@annotation(org.springframework.transaction.annotation.Transactional)

//只有一个参数且参数上声明了Classified注解
@args(com.xyz.security.Classified)

逻辑运算符支持

&& ,||, !分别表示与、或、非

execution(* com.xyz.service.*.*(..)) && execution(* set*(..))