Pointcut 表达式

今天介绍 Pointcut 的表达式
通配符
常见的通配符如下
..
含义一:方法表达式中、代表任意数量的参数
@Service
public class HelloService {
public void sayHi(String name) {
System.out.println("hi," + name);
}
public void sayHi(String firstName, String lastName) {
System.out.println("hi," + firstName + lastName);
}
}
@Pointcut("execution(public void com.example.junitspringboot.service.HelloService.sayHi(..))")
public void pointcut(){}
那么上面的 Pointcut 表达式就能将 HelloService 中的两个连接点都包括进去。
- 连接点:程序执行的某个特定位置,比如某个方法调用前、调用后,方法抛出异常后,对类成员的访问以及异常处理程序块的执行等。一个类或一段程序代码拥有一些具有边界性质的特定点,这些代码中的特定点就是连接点。它自身还可以嵌套其他的 Joinpoint。AOP 中的 Joinpoint 可以有多种类型:构造方法调用,字段的设置和获取,方法的调用,方法的执行,异常的处理执行,类的初始化。Spring 仅支持方法执行类型的 Joinpoint。
含义二:类定义表达式中、代表任意子包
@Component
@Aspect
public class ServiceAop {
@Pointcut("execution(public void com.example.junitspringboot..HelloService.sayHi(..))")
public void pointcut(){}
@Around("pointcut()")
public Object before(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("before");
return proceedingJoinPoint.proceed();
}
}
// 注意包名
package com.example.junitspringboot.service.inner;
import org.springframework.stereotype.Service;
@Service("innerHelloService")
public class HelloService {
public void sayHi(String firstName, String lastName) {
System.out.println("hi," + firstName + lastName);
}
}
// 注意包名
package com.example.junitspringboot.service;
public class HelloService {
public void sayHi(String name) {
System.out.println("hi," + name);
}
}
+
匹配给定类及其子类
public interface Person {
void say();
}
@Service
public class Man implements Person{
@Override
public void say() {
System.out.println("man");
}
}
@Service
public class Woman implements Person {
@Override
public void say() {
System.out.println("woman");
}
}
@Pointcut("within(com.example.junitspringboot.service.Person+)")
public void pointcut(){}
那么接口 Person 的子类所有实现的方法都会被增强。
*
匹配任意数量的字符
// com.example.junitspringboot.service 包所有的类的所有方法
@Pointcut("within(com.example.junitspringboot.service.*)")
public void pointcut1(){}
// 所有以 say 开头的方法
@Pointcut("execution(* say*(..))")
public void pointcut2(){}
execution
使用得最多的表达式、用于指定方法的执行。? 表示非必填
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?
name-pattern(param-pattern) throws-pattern?)
- modifiers-pattern? 表示修饰符、如 public、protected
- ret-type-pattern 返回类型、必填。 如果使用通配符 * 代表任意的返回类型
- declaring-type-pattern? 表示声明方法的类。
- name-pattern 表示方法名。
- param-pattern 表示方法参数、如果使用通配符 .. 则代表任意参数
- throws-pattern? 表示方法抛出的异常
例子
execution(public * com.example..say*(..))
- 修饰符为 public
- 任意返回类型
- 在 com.example 包或者其子包下
- 方法名称以 say 开头
- 任意参数
@Pointcut("execution( * say*(..))")
- 任意返回类型
- 方法名称以 say 开头
- 任意参数
@Pointcut("execution(* *(..) throws Exception)")
- 方法声明抛出 Exception 的任意方法
within
指定特定类型、类型中所有的方法都被拦截。
@Pointcut("within(com.example.junitspringboot.service.Person)")
- Person 类所有外部的方法调用都被拦截
@Pointcut("within(com.example.junitspringboot.service.Person+)")
- Person 类及其子类所有外部的方法调用都被拦截
@Pointcut("within(com.example.junitspringboot.service..*)"
- 所有在 com.example.junitspringboot.service 包以及子包下的所有类的所有外部调用方法
this
this通过判断代理类是否按类型匹配指定类来决定是否和切点匹配。 用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配。 this中使用的表达式必须是类型全限定名,不支持通配符。
public class ServiceAop implements Ordered {
@Pointcut("this(com.example.junitspringboot.service.ISwimming)")
public void thisPointcut(){}
@Before("thisPointcut()")
public void before(JoinPoint joinPoint) {
System.out.println("before");
}
@Override
public int getOrder() {
return 1;
}
}
// 使用引介使 Man 也实现 ISwimming 接口
@Component
@Aspect
public class IntroductionAop implements Ordered {
@DeclareParents(value = "com.example.junitspringboot.service.Man", defaultImpl = Swimming.class)
public ISwimming swimming;
@Override
public int getOrder() {
return 0;
}
}
// 微信公众号:CoderLi
public interface ISwimming {
void swim();
}
// 微信公众号:CoderLi
@Service
public class Man implements Person{
@Override
public void say() {
System.out.println("man");
}
}
ConfigurableApplicationContext context = SpringApplication.run(JunitSpringBootApplication.class, args);
context.getBean(Man.class).say();
((ISwimming) context.getBean(Man.class)).swim();
当我们调用 swim 方法的时候、会被拦截增强。当我们调用 say 方法的时候、同样也会被拦截增强,这个就是 this 会将代理类实现的其他接口的方法也会被拦截增强
target
target 通过判断目标类是否按类型匹配指定类来决定连接点是否匹配. 用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;
@Pointcut("target(com.example.junitspringboot.service.ISwimming)")
同样也是上面的例子。修改切点表达式为 target 、say 方法不再被拦截增强。
args
用来匹配参数
@Pointcut("args(..)")
- 匹配任意参数的方法
@Pointcut("args()")
- 匹配任何不带参数的方法
@target
匹配当被代理的目标对象对应的类型及其父类型上拥有指定的注解时
@Pointcut("@target(com.example.junitspringboot.anno.AopFlag) && within(com.example.junitspringboot..*)")
- 匹配在包 com.example.junitspringboot..* 下所有被 AopFlag 修饰的类的所有方法
@args
@args匹配被调用的方法上含有参数,且对应的参数类型上拥有指定的注解的情况。
@Pointcut("@args(com.example.junitspringboot.anno.AopFlag)")
// 微信公众号:CoderLi
@AopFlag
public class Data {
}
public interface Person {
void say(Data data);
}
@within
@within用于匹配被代理的目标对象对应的类型或其父类型拥有指定的注解的情况,但只有在调用拥有指定注解的类上的方法时才匹配。
@Pointcut("@within(com.example.junitspringboot.anno.AopFlag) && within(com.example.junitspringboot..*)")
这个功能上貌似跟 @target 有点像了
@annotation
也是比较常用的一个注解、用于匹配方法上拥有指定注解的情况。
@Pointcut("@annotation(com.example.junitspringboot.anno.AopFlag) && within(com.example.junitspringboot..*)")
bean
Spring 特有的一个表达式。
@Pointcut("bean(man)")
拦截该 bean 的所有方法
10 种切点的表达式介绍完毕
Pointcut 表达式的更多相关文章
- spring aop中pointcut表达式完整版
spring aop中pointcut表达式完整版 本文主要介绍spring aop中9种切入点表达式的写法 execute within this target args @target @with ...
- Spring Aop(三)——Pointcut表达式介绍
转发地址:https://www.iteye.com/blog/elim-2395255 3 Pointcut表达式介绍 3.1 表达式类型 标准的Aspectj Aop的pointcut的表达式类型 ...
- pointcut 表达式的含义
execution(* com.spring.dao.*.add*(..)) 第一个*表示任意返回值 第二个*表示com.spring.dao包中所有类 第三个*表示以add开头的所有方法 (..)表 ...
- Spring AOP 切点(pointcut)表达式
这遍文章将介绍Spring AOP切点表达式(下称表达式)语言,首先介绍两个面向切面编程中使用到的术语. 连接点(Joint Point):广义上来讲,方法.异常处理块.字段这些程序调用过程中可以抽像 ...
- Spring AOP AspectJ Pointcut 表达式例子
主要来源:http://howtodoinjava.com/spring/spring-aop/writing-spring-aop-aspectj-pointcut-expressions-with ...
- aop point-cut表达式
好多博客写的云里雾里,大多都有一点毛病.大家还是以官网为准 @官网文档 官网截图 modifiers-pattern:修饰符 ret-type-pattern:方法返回类型 declaring-typ ...
- Spring AOP 之二:Pointcut注解表达式
简介 在Spring AOP概述中我们重点注意的是AOP的整体流程和Advice,简化了一些其他的东西,其中就有一些对灵活应用Spring AOP很重要的知识点,例如Pointcut表达式,下面就介绍 ...
- Spring入门之AOP实践:@Aspect + @Pointcut + @Before / @Around / @After
零.准备知识 1)AOP相关概念:Aspect.Advice.Join point.Pointcut.Weaving.Target等. ref: https://www.cnblogs.com/zha ...
- 【Spring AOP】切入点表达式(四)
一.切入点指示符 切入点指示符用来指示切入点表达式目的,在Spring AOP中目前只有执行方法这一个连接点,Spring AOP支持的AspectJ切入点指示符如下: execution:用于匹配方 ...
随机推荐
- 洛谷 P4292 - [WC2010]重建计划(长链剖分+线段树)
题面传送门 我!竟!然!独!立!A!C!了!这!道!题!incredible! 首先看到这类最大化某个分式的题目,可以套路地想到分数规划,考虑二分答案 \(mid\) 并检验是否存在合法的 \(S\) ...
- 自助分析工具Power BI的简介和应用
作为一名资深的IT技术人,特别喜欢学习和尝试新技术,也勇于接受挑战,勇于创新,不仅能发现问题,更要解决实际的疑难杂症,闲暇时光也乐于分享一些技术干货.记得2017年的时候,华章出版社的编辑通过网上找到 ...
- 解决Gitlab的The remote end hung up unexpectedly错误,解决RPC failed; HTTP 413 curl 22 The requested URL returned error: 413 Request Entity Too Large问题
解决Gitlab的The remote end hung up unexpectedly错误 解决RPC failed; HTTP 413 curl 22 The requested URL retu ...
- confluence——实现
基于CentOS6.9 [root@localhost ~]# yum install mysql mysql-server -y [root@localhost ~]#yum install -y ...
- PHP-FPM运行状态的实时查看及监控详解
https://www.jb51.net/article/97640.htm https://blog.csdn.net/Dr_cokiy/article/details/105580758
- Xpath解析库的使用
### Xpath常用规则 ## nodename 选取此节点的所有子节点 ## / 从当前节点选取直接子节点 ## // 从当前节点选取子孙节点 ## . 选取当前节点 ## .. 选取当前节点的父 ...
- python爬虫采集
python爬虫采集 最近有个项目需要采集一些网站网页,以前都是用php来做,但现在十分流行用python做采集,研究了一些做一下记录. 采集数据的根本是要获取一个网页的内容,再根据内容筛选出需要的数 ...
- java中接口可以继承接口
今天阅读别人的代码才发现,接口是可以继承接口的 一个类只能extends一个父类,但可以implements多个接口. 一个接口则可以同时extends多个接口,却不能implements任何接口. ...
- 学习java 7.28
学习内容: Applet Applet一般称为小应用程序,Java Applet就是用Java语言编写的这样的一些小应用程序,它们可以通过嵌入到Web页面或者其他特定的容器中来运行,也可以通过Java ...
- day05 连表查询与子查询
day05 连表查询与子查询 昨日内容回顾 表关系之一对一 换位思考之后得出两边都是不可以 要么是没有关系,要么是一对一 一对一的表关系外键虽然建在哪个都可以,但是建议建在查询频率多的表上 # 外键其 ...