定义过滤切入点函数时,是直接把execution已定义匹配表达式作为值传递给通知类型的如下:
除了上述方式外,还可采用与ApectJ中使用pointcut关键字类似的方式定义切入点表达式如下,使用@Pointcut注解:
使用@Pointcut注解进行定义,应用到通知函数afterDemo()时直接传递切点表达式的函数名称myPointcut()即可,比较简单,下面接着介绍切点指示符。
为了方法通知应用到相应过滤的目标方法上,SpringAOP提供了匹配表达式,这些表达式也叫切入点指示符
在定义匹配表达式时,通配符几乎随处可见,如*
..
+
,它们的含义如下:
*
:匹配任意数量的字符
..
:匹配方法定义中的任意数量的参数,此外还匹配类定义中的任意数量包
+
:匹配给定类的任意子类
为了方便类型(如接口、类名、包名)过滤方法,Spring AOP 提供了within关键字。其语法格式如下:
type name 则使用包名或者类名替换即可,来点案例吧。
/** 匹配com.somnus.dao包及其子包中所有类中的所有方法 */
@Pointcut("within(com.somnus.dao..*)")
/** 匹配UserDaoImpl类中所有方法 */
@Pointcut("within(com.somnus.dao.UserDaoImpl)")
/** 匹配UserDaoImpl类及其子类中所有方法 */
@Pointcut("within(com.somnus.dao.UserDaoImpl+)")
/** 匹配所有实现UserDao接口的类的所有方法 */
@Pointcut("within(com.somnus.dao.UserDao+)")
如果想根据方法签名进行过滤,关键字execution可以帮到我们,语法表达式如下
对于给定的作用域、返回值类型、完全限定类名以及参数匹配的方法将会应用切点函数指定的通知,这里给出模型案例:
/** 匹配UserDaoImpl类中的所有方法 */
@Pointcut("execution(* com.somnus.dao.UserDaoImpl.*(..))")
/** 匹配UserDaoImpl类中的所有公共的方法 */
@Pointcut("execution(public * com.somnus.dao.UserDaoImpl.*(..))")
/** 匹配UserDaoImpl类中的所有公共方法并且返回值为int类型 */
@Pointcut("execution(public int com.somnus.dao.UserDaoImpl.*(..))")
/** 匹配UserDaoImpl类中第一个参数为int类型的所有公共的方法 */
@Pointcut("execution(public * com.somnus.dao.UserDaoImpl.*(int , ..))")
- bean:Spring AOP扩展的,AspectJ没有对于指示符,用于匹配特定名称的Bean对象的执行方法;
/** 匹配名称中带有后缀Service的Bean */
@Pointcut("bean(*Service)")
- this :用于匹配当前AOP代理对象类型的执行方法;请注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配
/** 匹配了任意实现了UserDao接口的代理对象的方法进行过滤 */
@Pointcut("this(com.somnus.spring.springAop.dao.UserDao)")
- target :用于匹配当前目标对象类型的执行方法;
/** 匹配了任意实现了UserDao接口的目标对象的方法进行过滤 */
@Pointcut("target(com.somnus.spring.springAop.dao.UserDao)")
- @within:用于匹配所有持有指定注解类型内的方法;请注意与within是有区别的, within是用于匹配指定类型内的方法执行;
/** 匹配使用了MarkerAnnotation注解的类(注意是类) */
@Pointcut("@within(com.somnus.spring.annotation.MarkerAnnotation)")
- @annotation: 根据所应用的注解进行方法过滤
/** 匹配使用了MarkerAnnotation注解的方法(注意是方法) */
@Pointcut("@annotation(com.somnus.spring.annotation.MarkerAnnotation)")
这里最后说明一点,切点指示符可以使用运算符语法进行表达式的混编,如and、or、not(或者&&、||、!),如下一个简单例子:
/** 匹配了任意实现了UserDao接口的目标对象的方法并且该接口不在com.somnus.dao包及其子包下 */
@Pointcut("target(com.somnus.spring.springAop.dao.UserDao) !within(com.somnus.dao..*)")
/** 匹配了任意实现了UserDao接口的目标对象的方法并且该方法名称为addUser */
@Pointcut("target(com.somnus.spring.springAop.dao.UserDao) && execution(* com.somnus.spring.springAop.dao.UserDao.addUser(..))")