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. 【 [SCOI2016]幸运数字】

    P3292 [SCOI2016]幸运数字 想法 倍增加上线性基就行惹 线性基的合并可以通过把一个线性基的元素插入到另一个里实现 #include<iostream> #include< ...

  2. 如何使用scp在Linux服务器的后台传输文件?

    目录 一.上传 常规操作 建议 后台运行 二.下载 两台服务器间文件如何传输?对于小文件,可以先从Linux服务器传到window,再传到另一台服务器.对于大的文件,如测序数据.比对文件等.这样的方法 ...

  3. HTML三层界面显示

    1.效果示意图 2.主要标签属性 3.实现代码 1.效果示意图 要实现类似如下效果:点击"大模态框",中间出现一层遮盖整个页面的半透明页面,最上面出现"Large mod ...

  4. 推荐一个latex简历模板的网站给大家

    http://www.rpi.edu/dept/arc/training/latex/resumes/ Using the LaTeX Resume Templates A group of resu ...

  5. CAS简介

    概念 CAS(Compare And Swap 比较并交换),是 乐观锁 的一种典型实现机制. 乐观锁主要的两个步骤:冲突检测.数据更新. 当多个线程尝试使用CAS同时更新通过一个变量的时候,只有一个 ...

  6. GraphScope 集群部署

    GraphScope 集群部署 1 k8s集群搭建 大致步骤如下: 安装docker.在ubuntu上,可以简单的通过命令sudo apt install docker.io来安装. 安装kubele ...

  7. 18. MYSQL 字符编码配置

    MYSQL 5.7版本的my.ini 在C盘隐藏文件夹下 C:\ProgramData\MySQL\MySQL Server 5.7 [client] default-character-set=ut ...

  8. ORACLE 查询sql和存储性能思路

    1.确定session id 如果是存储过程,在程序开头设置客户端标识.并根据标识获取session id. DBMS_SESSION.set_identifier('XXX'); select * ...

  9. Linux基础命令---mget获取ftp文件

    mget 使用lftp登录mftp服务器之后,可以使用mget指令从服务器获取文件.mget指令可以使用通配符,而get指令则不可以.   1.语法       mget [-E]  [-a]  [- ...

  10. ubuntu基础

    下载地址: http://cdimage.ubuntu.com/releases/ #:配置多网卡静态IP地址和路由 root@ubuntu:~# vim /etc/netplan/01-netcfg ...