本文主要介绍spring aop中9种切入点表达式的写法

  1. execute
  2. within
  3. this
  4. target
  5. args
  6. @target
  7. @within
  8. @annotation
  9. @args

0. 示例代码git地址

​​​​​​spring-aop-demo: spring aop 切入点表达式完整示例

PS:在spring中,不管是连接点还是切入点,这些点指的都是方法,因为spring只支持方法类型的连接点。

1.execute表达式

拦截任意公共方法

execution(public * *(..))

拦截以set开头的任意方法

execution(* set*(..))

拦截类或者接口中的方法

execution(* com.xyz.service.AccountService.*(..))

拦截AccountService(类、接口)中定义的所有方法

拦截包中定义的方法,不包含子包中的方法

execution(* com.xyz.service.*.*(..))

拦截com.xyz.service包中所有类中任意方法,不包含子包中的类

拦截包或者子包中定义的方法

execution(* com.xyz.service..*.*(..))

拦截com.xyz.service包或者子包中定义的所有方法

2.within表达式

表达式格式:包名.* 或者 包名..*

拦截包中任意方法,不包含子包中的方法

within(com.xyz.service.*)

拦截service包中任意类的任意方法

拦截包或者子包中定义的方法

within(com.xyz.service..*)

拦截service包及子包中任意类的任意方法

3.this表达式

代理对象为指定的类型会被拦截

目标对象使用aop之后生成的代理对象必须是指定的类型才会被拦截,注意是目标对象被代理之后生成的代理对象和指定的类型匹配才会被拦截

this(com.xyz.service.AccountService)

示例

this表达式的使用,可能不是很好理解,用示例说明一下:

业务接口:

public interface IService {void m1();
}

业务类:

@Slf4j
@Service
public class ServiceImpl implements IService {@Overridepublic void m1() {log.info("切入点this测试!");}
}

定义切面:

@Aspect
@Component
@Slf4j
public class Interceptor1 {@Pointcut("this(com.ms.aop.jthis.demo1.ServiceImpl)")public void pointcut() {}@Around("pointcut()")public Object invoke(ProceedingJoinPoint invocation) throws Throwable {log.info("方法执行之前");Object result = invocation.proceed();log.info("方法执行完毕");return result;}
}

测试:

@ComponentScan(basePackageClasses = {Client.class})
@EnableAspectJAutoProxy
@Slf4j
public class Client {public static void main(String[] args) {AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Client.class);IService service = annotationConfigApplicationContext.getBean(IService.class);service.m1();log.info("{}", service instanceof ServiceImpl);}
}

执行结果

10:27:12.277 [main] INFO com.ms.aop.jthis.demo1.ServiceImpl - 切入点this测试!
10:27:12.277 [main] INFO com.ms.aop.jthis.demo1.Client - false

@EnableAspectJAutoProxy:表示若spring创建的对象如果实现了接口,默认使用jdk动态代理,如果没有实现接口,使用cglib创建代理对象。

所以 service 是使用jdk动态代理生成的对象,service instanceof ServiceImpl 为 false

@Pointcut("this(com.ms.aop.jthis.demo1.ServiceImpl)")表示:被spring代理之后生成的对象必须为com.ms.aop.jthis.demo1.ServiceImpl才会被拦截,但是service不是ServiceImpl类型的对象了,所以不会被拦截。

修改代码:

@EnableAspectJAutoProxy(proxyTargetClass = true)

proxyTargetClass=true表示使用cglib来生成代理对象

执行结果:

10:34:50.736 [main] INFO com.ms.aop.jthis.demo1.Interceptor1 - 方法执行之前
10:34:50.755 [main] INFO com.ms.aop.jthis.demo1.ServiceImpl - 切入点this测试!
10:34:50.756 [main] INFO com.ms.aop.jthis.demo1.Interceptor1 - 方法执行完毕
10:34:50.756 [main] INFO com.ms.aop.jthis.demo1.Client - true

service 为 ServiceImpl类型的对象,所以会被拦截

4.target表达式

目标对象为指定的类型被拦截

target(com.xyz.service.AccountService)

目标对象为AccountService类型的会被代理

示例

public interface IService {void m1();
}
@Slf4j
@Component
public class ServiceImpl implements IService {@Overridepublic void m1() {log.info("切入点target测试!");}
}
@Aspect
@Component
@Slf4j
public class Interceptor1 {@Pointcut("target(com.ms.aop.target.ServiceImpl)")public void pointcut() {}@Around("pointcut()")public Object invoke(ProceedingJoinPoint invocation) throws Throwable {log.info("方法执行之前");Object result = invocation.proceed();log.info("方法执行完毕");return result;}
}
@ComponentScan(basePackageClasses = {Client.class})
@EnableAspectJAutoProxy
public class Client {public static void main(String[] args) {AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Client.class);IService service = annotationConfigApplicationContext.getBean(IService.class);service.m1();}
}

执行结果:

10:49:01.674 [main] INFO com.ms.aop.target.Interceptor1 - 方法执行之前
10:49:01.674 [main] INFO com.ms.aop.target.ServiceImpl - 切入点target测试!
10:49:01.674 [main] INFO com.ms.aop.target.Interceptor1 - 方法执行完毕

this 和 target 的不同点

  1. this作用于代理对象,target作用于目标对象
  2. this表示目标对象被代理之后生成的代理对象和指定的类型匹配会被拦截,匹配的是代理对象
  3. target表示目标对象和指定的类型匹配会被拦截,匹配的是目标对象

5.args 表达式

匹配方法中的参数

@Pointcut("args(com.ms.aop.args.demo1.UserModel)")

匹配只有一个参数,且类型为com.ms.aop.args.demo1.UserModel

匹配多个参数

args(type1,type2,typeN)

匹配任意多个参数

@Pointcut("args(com.ms.aop.args.demo1.UserModel,..)")

匹配第一个参数类型为com.ms.aop.args.demo1.UserModel的所有方法, .. 表示任意个参数

6.@target表达式

匹配的目标对象的类有一个指定的注解

@target(com.ms.aop.jtarget.Annotation1)

目标对象中包含com.ms.aop.jtarget.Annotation1注解,调用该目标对象的任意方法都会被拦截

7.@within表达式

指定匹配必须包含某个注解的类里的所有连接点

@within(com.ms.aop.jwithin.Annotation1)

声明有com.ms.aop.jwithin.Annotation1注解的类中的所有方法都会被拦截

@target 和 @within 的不同点

  1. @target(注解A):判断被调用的目标对象中是否声明了注解A,如果有,会被拦截

  2. @within(注解A): 判断被调用的方法所属的类中是否声明了注解A,如果有,会被拦截

  3. @target关注的是被调用的对象,@within关注的是调用的方法所在的类

8.@annotation表达式

匹配有指定注解的方法(注解作用在方法上面)

@annotation(com.ms.aop.jannotation.demo2.Annotation1)

被调用的方法包含指定的注解

9.@args表达式

方法参数所属的类型上有指定的注解,被匹配

注意:是方法参数所属的类型上有指定的注解,不是方法参数中有注解

  • 匹配1个参数,且第1个参数所属的类中有Anno1注解
@args(com.ms.aop.jargs.demo1.Anno1)
  • 匹配多个参数,且多个参数所属的类型上都有指定的注解
@args(com.ms.aop.jargs.demo1.Anno1,com.ms.aop.jargs.demo1.Anno2)
  • 匹配多个参数,且第一个参数所属的类中有Anno1注解
@args(com.ms.aop.jargs.demo2.Anno1,..)

分享一些实用的java技术(爬虫、消息服务、分布式事务、分布式任务调度、互联网金融等),喜欢的请关注公众号:路人甲Java

pointcut表达式相关推荐

  1. SpringBoot使用AOP,PointCut表达式详解以及使用

    SpringBoot使用AOP,PointCut表达式详解以及使用 1.相关注解 2.PointCut 表达式详解 2.1 execution: 2.1 within: 2.3. this: 2.4. ...

  2. SpringBoot的AOP中PointCut表达式详解以及使用

    首先,在pom.xml中添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifa ...

  3. Pointcut 表达式

    AOP 概念篇 今天介绍 Pointcut 的表达式 通配符 常见的通配符如下 - 含义一:方法表达式中.代表任意数量的参数 @Service public class HelloService {p ...

  4. Pointcut表达式类型

    Pointcut表达式类型 标准的AspectJ Aop的pointcut的表达式类型是很丰富的,但是Spring Aop只支持其中的9种,外加Spring Aop自己扩充的一种一共是11(10+1) ...

  5. spring aop中pointcut表达式

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

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

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

  7. Spring AOP 切点 Pointcut 表达式介绍与使用

    一.前言 面向切面编程 AOP 是一种常见的编程思想,是面向对象编程的一种补充,AOP 框架通过修改源代码,将处理逻辑编织到指定的业务模块中 常见的处理比如:在方执行法前进行校验,在方法执行后进行日志 ...

  8. @Pointcut注解表达式介绍

    1 表达式类型 标准的Aspectj Aop的pointcut的表达式类型是很丰富的,但是Spring Aop只支持其中的9种,外加Spring Aop自己扩充的一种一共是10种类型的表达式,分别如下 ...

  9. Spring AOP中@Pointcut切入点表达式详解

    目录 一.瞅一眼标准的AspectJ Aop的pointcut的表达式 二.SpringAop的十一种AOP表达式 三.演示使用 1.execution: 2.within: 3.this: 4.ta ...

最新文章

  1. c++回调函数 callback
  2. 百度商桥修改服务器,百度商桥 · 响应式网站编辑器使用手册 · 看云
  3. Android4.0 修改系统屏幕分辨率方法
  4. 使用 AppleScript 在 Chrome 中查看当前 Safari 打开的网页
  5. python库--requests
  6. Access链接表的使用
  7. Asp.Net Core Mvc上Json序列化首字母大小写的问题
  8. 产生am信号 matlab,基于MATLAB的AM信号的调制与解调论文.doc
  9. 第十二课:OpenGL扩展
  10. mysql基于SpringBoot的“1818小酒馆”商城网站的设计与实现毕业设计源码192004
  11. 关于程序员的非技术面试题全在这里。
  12. 零基础入门学习python笔记-day1:程序开发谋定而后动
  13. 你绝对能看懂的Kafka源代码分析-Kafka Producer设计分析
  14. 台积电:3纳米芯片工厂地址首选台湾 美国次之
  15. 2019-7-27 [MySQL] DQL 简单查询[别名/去重/运算] 条件查询 排序查询 聚合查询 分组查询 导出与导入 多表操作[一对多/多对多][创外键 创联合主键 约束 添加 删除 测试]
  16. 微信小程序集成实时音视频通话功能
  17. 交叉编译和交叉工具链
  18. 编译原理之形式语言文法分类
  19. linux amd显卡双屏,Ubuntu14.04安装AMD显卡驱动双屏显示器完全解决方案
  20. Lucid年运营亏损15亿美元:背靠中东资本 市值300亿美元超Rivian​

热门文章

  1. 【第14题】输入三个整数 x,y,z,请把这三个数由小到大输出
  2. 上传应用程序到谷歌商店_将Google图书搜索集成到PHP应用程序中
  3. 【IT项目管理】第9章 习题
  4. Win10家庭版任务管理器被禁用,解除方法
  5. 网页设计待办事项闹钟php,创建待办事件列表
  6. 京东数据化运营(一)- 流量篇
  7. python 实现罗德里格斯公式Rodrigues 旋转向量到旋转矩阵转化
  8. 小易的考试成绩(0 -1背包问题)
  9. EMC原理-传导(共模、差模)与辐射(近场、远场)详解
  10. 基金投资从入门到精通]之“投资技巧篇