1. AOP 概念篇

今天介绍 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 表达式的更多相关文章

  1. spring aop中pointcut表达式完整版

    spring aop中pointcut表达式完整版 本文主要介绍spring aop中9种切入点表达式的写法 execute within this target args @target @with ...

  2. Spring Aop(三)——Pointcut表达式介绍

    转发地址:https://www.iteye.com/blog/elim-2395255 3 Pointcut表达式介绍 3.1 表达式类型 标准的Aspectj Aop的pointcut的表达式类型 ...

  3. pointcut 表达式的含义

    execution(* com.spring.dao.*.add*(..)) 第一个*表示任意返回值 第二个*表示com.spring.dao包中所有类 第三个*表示以add开头的所有方法 (..)表 ...

  4. Spring AOP 切点(pointcut)表达式

    这遍文章将介绍Spring AOP切点表达式(下称表达式)语言,首先介绍两个面向切面编程中使用到的术语. 连接点(Joint Point):广义上来讲,方法.异常处理块.字段这些程序调用过程中可以抽像 ...

  5. Spring AOP AspectJ Pointcut 表达式例子

    主要来源:http://howtodoinjava.com/spring/spring-aop/writing-spring-aop-aspectj-pointcut-expressions-with ...

  6. aop point-cut表达式

    好多博客写的云里雾里,大多都有一点毛病.大家还是以官网为准 @官网文档 官网截图 modifiers-pattern:修饰符 ret-type-pattern:方法返回类型 declaring-typ ...

  7. Spring AOP 之二:Pointcut注解表达式

    简介 在Spring AOP概述中我们重点注意的是AOP的整体流程和Advice,简化了一些其他的东西,其中就有一些对灵活应用Spring AOP很重要的知识点,例如Pointcut表达式,下面就介绍 ...

  8. Spring入门之AOP实践:@Aspect + @Pointcut + @Before / @Around / @After

    零.准备知识 1)AOP相关概念:Aspect.Advice.Join point.Pointcut.Weaving.Target等. ref: https://www.cnblogs.com/zha ...

  9. 【Spring AOP】切入点表达式(四)

    一.切入点指示符 切入点指示符用来指示切入点表达式目的,在Spring AOP中目前只有执行方法这一个连接点,Spring AOP支持的AspectJ切入点指示符如下: execution:用于匹配方 ...

随机推荐

  1. 洛谷 P4426 - [HNOI/AHOI2018]毒瘤(虚树+dp)

    题面传送门 神仙虚树题. 首先考虑最 trival 的情况:\(m=n-1\),也就是一棵树的情况.这个我相信刚学树形 \(dp\) 的都能够秒掉罢(确信).直接设 \(dp_{i,0/1}\) 在表 ...

  2. Sums gym100753M

    Sums gym100753M 同余最短路模板,然而这个东西貌似也可以做去年D1T2 首先我们选择一个模数作为基准,然后剩下的这样连边: 对于一个面值为 x 的硬币 ,当前在 u 这个点(感性理解一下 ...

  3. R语言矩阵相关性计算及其可视化?

    目录 1. 矩阵相关性计算方法 base::cor/cor.test psych::corr.test Hmisc::rcorr 其他工具 2. 相关性矩阵转化为两两相关 3. 可视化 corrplo ...

  4. 【基因组注释】GMAP安装使用问题

    homology策略预测基因结构,下载了公共mRNA/CDS序列,考虑用gmap比对.本来是个很简单的脚本,但总是不那么顺利. 无论是用conda安装,还是源码安装较新版本,都存在问题. gmap_b ...

  5. perl中tr的用法(转载)

    转载:http://blog.sina.com.cn/s/blog_4a0824490101hncz.html (1)/c表示把匹配不上的字符进行替换. $temp="AAAABCDEF&q ...

  6. MySQL 的查询优化

    说起 MySQL 的查询优化,相信大家收藏了一堆奇技淫巧:不能使用 SELECT *.不使用 NULL 字段.合理创建索引.为字段选择合适的数据类型..... 你是否真的理解这些优化技巧?是否理解它背 ...

  7. bluetooth sig bluetooth asia-深圳之行

    18年5月30日深圳参见蓝牙展会 主要了解下面 使用蓝牙和区块链构建室内导航定位系统和去中心化的MESH网络 -- 核心是通过iBeacon 来广播数据,典型用例是手机对手机的使用蓝牙进行交互,业界称 ...

  8. 进程和线程操作系统转载的Mark一下

    https://www.cnblogs.com/leisure_chn/p/10393707.html Linux的进程线程及调度 本文为宋宝华<Linux的进程.线程以及调度>学习笔记. ...

  9. 用原生CSS编写-怦怦跳的心

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  10. 表格合并单元格【c#】

    gridBranchInfo.DataSource = dtBranchViewList; gridBranchInfo.DataBind(); Random random = new Random( ...