Elim的博客

用来记录一些原创性的总结


Elim

3 Pointcut表达式介绍

3.1 表达式类型

标准的Aspectj Aop的pointcut的表达式类型是很丰富的,但是Spring Aop只支持其中的9种,外加Spring Aop自己扩充的一种一共是10种类型的表达式,分别如下。

3.2 使用示例

3.2.1 execution

execution是使用的最多的一种Pointcut表达式,表示某个方法的执行,其标准语法如下。

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

modifiers-pattern表示方法的访问类型,public等;ret-type-pattern表示方法的返回值类型,如String表示返回类型是String,“*”表示所有的返回类型;declaring-type-pattern表示方法的声明类,如“com.elim..*”表示com.elim包及其子包下面的所有类型;name-pattern表示方法的名称,如“add*”表示所有以add开头的方法名;param-pattern表示方法参数的类型,name-pattern(param-pattern)其实是一起的表示的方法集对应的参数类型,如“add()”表示不带参数的add方法,“add(*)”表示带一个任意类型的参数的add方法,“add(*,String)”则表示带两个参数,且第二个参数是String类型的add方法;throws-pattern表示异常类型;其中以问号结束的部分都是可以省略的。

3.2.2 within

within是用来指定类型的,指定类型中的所有方法将被拦截。

3.2.3 this

Spring Aop是基于代理的,this就表示代理对象。this类型的Pointcut表达式的语法是this(type),当生成的代理对象可以转换为type指定的类型时则表示匹配。基于JDK接口的代理和基于CGLIB的代理生成的代理对象是不一样的。

3.2.4 target

Spring Aop是基于代理的,target则表示被代理的目标对象。当被代理的目标对象可以被转换为指定的类型时则表示匹配。

3.2.5 args

args用来匹配方法参数的。

3.2.6 @target

@target匹配当被代理的目标对象对应的类型及其父类型上拥有指定的注解时。

3.2.7 @args

@args匹配被调用的方法上含有参数,且对应的参数类型上拥有指定的注解的情况。

3.2.8 @within

@within用于匹配被代理的目标对象对应的类型或其父类型拥有指定的注解的情况,但只有在调用拥有指定注解的类上的方法时才匹配

3.2.9 @annotation

@annotation用于匹配方法上拥有指定注解的情况。

3.2.10 bean

bean用于匹配当调用的是指定的Spring的某个bean的方法时。

3.3 表达式组合

表达式的组合其实就是对应的表达式的逻辑运算,与、或、非。可以通过它们把多个表达式组合在一起。

3.4 基于Aspectj注解的Pointcut表达式应用

在使用基于Aspectj注解的Spring Aop时,我们可以把通过@Pointcut注解定义Pointcut,指定其表达式,然后在需要使用Pointcut表达式的时候直接指定Pointcut。

@Component
@Aspect
public class MyAspect {

	@Pointcut("execution(* add(..))")
	private void beforeAdd() {}
	
	@Before("beforeAdd()")
	public void before() {
		System.out.println("-----------before-----------");
	}
	
}

上面的代码中我们就是在@Before()中直接指定使用当前类定义的beforeAdd()方法对应的Pointcut的表达式,如果我们需要指定的Pointcut定义不是在当前类中的,我们需要加上类名称,如下面这个示例中引用的就是定义在MyService中的add()方法上的Pointcut的表达式。

@Before("com.elim.spring.aop.service.MyService.add()")
public void before2() {
	System.out.println("-----------before2-----------");
}

当然了,除了通过引用Pointcut定义间接的引用其对应的Pointcut表达式外,我们也可以直接使用Pointcut表达式的,如下面这个示例就直接在@Before中使用了Pointcut表达式。

/**
 * 所有的add方法的外部执行时
 */
@Before("execution(* add())")
public void beforeExecution() {
	System.out.println("-------------before execution---------------");
}

(注:本文是基于Spring4.1.0所写,写于2017年1月14日星期六)