Spring AOP切面实现:定义切入点语法和切入点指示符

  • Post author:
  • Post category:其他

一、定义切入点:

在@AspectJ风格的AOP中,切入点签名采用一个普通的方法定义(方法体通常为空)来提供(方法名即为切点名),且该方法的返回值必须为void,切入点表达式需使用@Pointcut注解来标注。如下:

//配置切入点,该方法无方法体,主要为方便同类中其他方法使用此处配置的切入点
	@Pointcut("execution(public * com.learn.spring..*.*(..))")
	private void pointcut() {
	}

一旦采用上面的代码片段定义了名为pointcut的切入点之后,程序就可以多次重复使用该切点了,甚至可以在其他切面类、其他包的切面类里使用该切点,至于是否可以在其他切面类、其他包下使用这个切点,那就要看该方法前的访问控制修饰符了——本例中pointcut使用private修饰,则意味着仅能在当前切面类中使用这个切点。

指定切入点的语法类似于Java中调用方法。假设在另一个类中调用上述代码段定义的切入点poingcut(),调用方式如下:

//引用时带上类名
	@After("LearnAspect.pointcut()")
	public void after()
	{
		System.out.println("调用LearnAspect的切入点pointcut()");
	}

二、切入点表达式:

切入点表达式,也就是组成@Pointcut注解的值。


类型匹配通配符

         *:匹配任何数量字符;

         ..:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数。

         +:匹配指定类型的子类型;仅能作为后缀放在类型模式后边。

示例:

java.lang.String : 匹配String类型

java.*.String : 匹配java包下的任何”一级子包“下的String类型.

java..* : 匹配java包及任何子包下的任何类型

java.lang.*ing : 匹配任何java.lang包下的以ing结尾的类型

java.lang.Number+ : 匹配java.lang包下的任何Number的自类型。如:java.lang.Interger、java.lang.BigInteger


Spring AOP支持的切入点指示符如下

execution:用于匹配方法执行的连接点;

语法:其中execution 是用的最多的,其格式为:
execution(modifiers-pattern? ret-type-pattern declaring-typ e-pattern? name-pattern(param-pattern)throws-pattern?)

  • modifiers-pattern:方法的操作权限

  • ret-type-pattern:必填,返回值,可以使用“*”进行模式匹配

  • declaring-type-pattern:方法所在的包

  • name-pattern:必填,方法名,可以使用“*”进行模式匹配

  • parm-pattern:必填,参数列表,可以使用“*”、“..”进行模式匹配

  • throws-pattern:异常

示例: 

public * *(..) : 任何公共方法的执行

* com.learn..Learn.*() : com.learn包以及子包下Learn类中的任何无参方法

* com.learn..*.*(..) : com.learn包以及子包下的任何类的任何方法

within:用于匹配指定类型内的方法执行;

语法:只能指定包路径,表示是某个包下或者子包下的所有方法。

示例:

within(com.learn.*)  : com.learn包下的所有方法。

within(com.learn..*) : com.learn包以及子包下的所有方法。

this:限制连接点匹配AOP代理的bean引用为指定类型的类

用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配;

语法:表达式必须是类型全限定名,不支持通配符

示例:

this(com.learn.ServiceManager) : 匹配实现了ServiceManager接口的代理对象的所有连接点,在Spring中只是方法执行的连接点

target:限制连接点匹配目标对象为指定的类

用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;

语法:表达式必须是类型全限定名,不支持通配符

示例:

target(com.learn.ServiceManager) : 匹配实现了ServiceManager接口的目标对象的所有连接点,在Spring中只是方法执行的连接点

args:用于匹配当前执行的方法传入的参数为指定类型的执行方法;

示例: args(java.io.Serializable,..) : 任何以一个接受传入参数为java.io.serializable开头,其后可跟任意个任意参数类型的执行方法


@within、@target、@annotation、@args这些语法形式主要是针对注解的。注解类型都必须是全限定类型名

@within:限制连接点匹配指定注解所标注的类型(当使用Spring AOP时,方法定义在由指定的注解所标注的类里);

示例: @within(com.learn.Table) : 任何目标对象持有Table注解的类方法。必须是在目标对象上声明这个注解,在接口上声明的对它不起作用

@target:限制连接点匹配特定的执行对象,这些对象对应的类要具有指定类型的注解;

示例:@target(com.learn.Table) : 任何目标对象持有Table注解的类方法。必须是在目标对象上声明这个注解,在接口上声明的对它不起作用

@args:限制连接点匹配参数由指定注解标注的执行方法;

示例:@args(com.learn.Table) : 任何一个只接受一个参数的方法,且传入参数持有Table注解

@annotation:限定匹配带有指定注解的连接点

示例:@annotation(com.learn.Table) : 当前执行方法上持有Table注解,将被匹配



bean:Spring AOP扩展的,AspectJ没有对于指示符,用于匹配特定名称的Bean对象的执行方法;

示例:bean(*Service) : 匹配所有以Service命名结尾的Bean



组合切点表达式

    Spring支持使用如下三个逻辑运算符来组合切入点表达式:

  • &&:要求连接点同时匹配两个切点表达式

  • ||:要求连接点匹配至少一个切入点表达式

  • !:要求连接点不匹配指定的切入点表达式


版权声明:本文为LittleSkey原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。