Spring Aspect的Execution表达式
参考博文:Spring Aspect的Execution表达式
我最近在学习spring 隐式装配和自动化配置,在学习aop切面配置的时候,意外发现我竟然对切面匹配规则一点都不了解,现在根据网上的博客(没有找到官网的文档),学习一下。
@Aspect
@Component
public class ControllerAspectj {//execution 表达式 匹配需要的方法@Pointcut("execution(* com.cybx..*.*(..))")public void pointCut() {//定义切点}@Before("pointCut()")public void before() {//System.out.println("执行方法前执行这个方法");}@After("pointCut()")public void after() {//System.out.println("执行方法后执行这个方法");}@Around("pointCut()")public Object around(ProceedingJoinPoint jp) throws Throwable {String className = jp.getTarget().getClass().getSimpleName();String methodName = jp.getSignature().getName() + "()";System.out.println("className===" + className);System.out.println("methodName===" + methodName);Object obj = jp.proceed();System.out.println("方法执行结束");return obj;}
}
基本语法
execution(<修饰符模式>? <返回类型模式> <方法名模式>(<参数模式>) <异常模式>?)
? 在正则中是0个或一个的意思,那这句话的意思就是:
<返回类型模式> <方法名模式>(<参数模式>) ----- 这些是必须的
<修饰符模式> <异常模式> ------ 这些不是必须的
各种切点定义
网上的博客说主要有:方法、类、类包、参数四种方式匹配,我根据个人理解自己重新进行分类。
不考虑包的方法匹配
这种匹配方式不考虑方法的包名。
- 无修饰符,不考虑方法参数
- 无修饰符,匹配方法参数
- 有修饰符,不考虑方法参数
有修饰符,匹配方法参数
第一种, 无修饰符,不考虑方法参数
匹配任意方法
execution(* *(..))
测试
@Aspect
@Component
public class ControllerAspectj {//后面就只贴这个代码//execution 表达式 匹配所有的@Pointcut("execution(* *(..))")public void pointCut() {//定义切点}@Before("pointCut()")public void before() {//System.out.println("执行方法前执行这个方法");}@After("pointCut()")public void after() {//System.out.println("执行方法后执行这个方法");}@Around("pointCut()")public Object around(ProceedingJoinPoint jp) throws Throwable {String className = jp.getTarget().getClass().getSimpleName();String methodName = jp.getSignature().getName() + "()";System.out.println("className===" + className);System.out.println("methodName===" + methodName);Object obj = jp.proceed();System.out.println("方法执行结束");return obj;}
}
测试结果:
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'redisTemplate' is expected to be of type [org.springframework.data.redis.core.StringRedisTemplate] but was actually of type [com.sun.proxy.$Proxy77]at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:378)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:207)at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1128)at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1056)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:566)... 72 more
测试项目无法启动了,因为这种匹配方法,匹配了所有的方法,但是有的方法是代理生成的,启动过程无法执行,目前这种匹配方式我用不到。
第二种, 无修饰符,匹配方法参数
匹配方法,第一个参数是String,第二个参数int
execution(* *(String, int))
匹配方法,第一个参数是String,第二个参数类型不限制
execution(* *(String,*))
匹配方法,第一个参数是String,不限制其它参数的
execution(* *(String,..))
匹配名称后缀是ByPage的方法,一个参数是String
execution(* *ByPage(String))
匹配名称前缀是get的方法,一个参数是String
execution(* get*(String))
这些匹配方式,我的项目无法测试,启动项目就会报错。
剩下的修饰符,就不啰嗦了,就是在这些匹配方式之前加上修饰符,例如:
execution(public * get*(String))
包含类包限制的方法匹配
这种方式的匹配就是把上述的方法的*替换成有类包限制的的表达式,例如:
匹配名称后缀是ByPage的方法,一个参数是String
execution(* *ByPage(String))
加上类包限制,只匹配com.test.Controller.TestController下的后缀为ByPage,参数为String的方法:
execution(* com.test.Controller.TestController.*ByPage(String))
如果还想匹配TestController的实现类的方法,加上一个+号:
execution(* com.test.Controller.TestController+.*ByPage(String))
如果想匹配com.test.Controller包下类的方法:
execution(* com.test.Controller.*.*ByPage(String))
如果想匹配com.test.Controller包以及子包中类的方法:
execution(* com.test.Controller..*.*ByPage(String))
其它的参数以及修饰符同上。
测试总结
上面提到的各种匹配,部分我都测试了,但是发现一个问题,如果代理执行的方法调用了内部的方法,无论这个方法的修饰符是什么,这个内部调用是不会被拦截的,网上其它博主也遇到类似的问题。
简单的解决办法,就是把这个内部方法写到其它类中,注入这个类,通过这个类调用方法。
可以参考这个博客,以及这个博客。
Spring Aspect的Execution表达式相关推荐
- spring AspectJ的Execution表达式
Aspectj切入点语法定义 在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点" 例如定义切入点表达式 execut ...
- Spring Aspect @PointCut(execution表达式)
execution(* com.sample.service.impl..*.*(..)) 解释如下: 符号 含义 execution() 表达式的主体: 第一个"*"符号 表示返 ...
- Spring AOP切入点@Pointcut -- execution表达式
Spring AOP 切入点@Pointcut – execution表达式 表达式示例 execution(* com.sample.service.impl..*.*(..)) 详述: execu ...
- 白话Spring(基础篇)---AOP(execution表达式)
[一知半解,就是给自己挖坑] 作为AOP的最后一节内容,我们来简单总结一下切面表达式上见的书写方法.下面的那内容有参考其他博文,在此先对开源博客的各位大神表示感谢! ----------------- ...
- Spring AspectJ Execution 表达式
1. 定义切点表达式 execution(* com.xinsui.service.impl..*.*(..)) execution(* *..impl..*.*(..)) 切点表达式分为五个部分 1 ...
- Spring AOP -- execution表达式
*:匹配任何数量字符: ..:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包:而在方法参数模式中匹配任何数量参数. +:匹配指定类型的子类型:仅能作为后缀放在类型模式后边. 表达式示例 exe ...
- Spring AOP 切点 Pointcut 表达式介绍与使用
一.前言 面向切面编程 AOP 是一种常见的编程思想,是面向对象编程的一种补充,AOP 框架通过修改源代码,将处理逻辑编织到指定的业务模块中 常见的处理比如:在方执行法前进行校验,在方法执行后进行日志 ...
- spring aop中pointcut表达式
spring aop中pointcut表达式 本文主要介绍spring aop中9种切入点表达式的写法 execute within this target args @target @within ...
- execution 表达式用法汇总
1.切所有controller下的请求 项目结构 任意公共方法的执行: 1 execution(public * (-)) ##public可以省略, 第一个 代表方法的任意返回值 第二个参数代表任意 ...
最新文章
- 2022-2028年中国三氟化氮行业市场调查研究及前瞻分析报告
- 将Nodelist快速转换为Array数组
- Python人脸识别+手机推送,老板来了你就会收到短信提示
- 二叉树展开为链表—leetcode114
- c语言在中职的作用,C语言程序下的中职教学论文
- 成考期末计算机组成原理,2020年10月自考02318计算机组成原理真题及答案
- map+shuffle+reducer
- 《FLUENT 14流场分析自学手册》——第2章 流体流动分析软件概述 2.1 CFD软件简介...
- 机器人体验营笔记(一)概要
- 计算机可以谭音乐吗,谭晶怎么被叫谭哈哈 《歌手》谭晶演唱什么歌曲
- Mac M1安装ta-lib
- excel中单元格的绝对引用和相对引用
- Redis缓存击穿、雪崩、穿透!(超详细)
- UVa12325 宝藏
- 定时器Timer使用
- 汽车美容店管理系统如何管理店铺数据?
- iso三体系认证有什么用
- 交换机-Exchanges
- 关于傅里叶变换的理解、快速傅里叶算法的推导以及蝶形运算的c语言实现
- 最简单的需求分析方法论