SpringAOP切点函数实现原理详解
作者:曾经那个少年 发布时间:2021-09-05 11:00:59
一:在函数入参中使用通配符
@AspectJ支持3种通配符
* :匹配任意字符,但它只能匹配上下文中的一个元素.
.. :匹配任意字符,可以匹配上下文中多个元素,但在表示类时,必须和*联合使用,而在表示入参时则单独使用
+:表示按类型匹配指定类的所有类,必须跟在类名后面,如com.smart.Car+ ;继承或扩展指定类的所有类,同时还包括指定类本身.
@AspectJ函数按其是否支持通配符及支持的程度,可以分为以下3类.
1):支持所有的通配符:execution(),within()
2):仅支持“+”通配符:args(),this(),target()
3):不支持通配符:@args(),within(),target();@annotation()
此外,args(),this(),target(),@args(),@within(),@target()和@annotation()这7个函数除了可以指定类名外,也可以指定变量名,并将目标对象中的变量绑定到增强的方法中.
二:切点函数详解
[1]:@annotation()
@annotation()表示标注了某个注解的所有方法.
eg:
package com.springboot.test;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class TestAspect {
@AfterReturning("@annotation(com.springboot.anno.NeedTest)")
public void needTestFun() {
System.out.println("needTestFun() executed!");
}
}
[2]:execution()
execution()是最常用的切点函数,其语法如下:
execution(<修饰符模式>?<返回类型模式><方法名模式>(<参数模式>) <异常模式>?)
除了返回类型模式,方法名模式,参数模式外,其他项都是可选的.
(1):通过方法签名定义切点
execution(public * *(..)):匹配所有目标类的public方法,第一个*代表返回类型,第二个*代表方法名,而..代表任意入参的方法.
execution(* *To(..)):匹配所有以To为后缀的方法,第一个*代表返回类型,而*To代表任意以To为后缀的方法.
(2):通过类定义切点
execution(* com.springboot.Waiter.*(..)):匹配Waiter接口的所有方法,第一个*代表返回任意类型;com.springboot.Waiter.*(..)代表Waiter接口的所有方法,
(3):通过类包定义切点
在类名模式串中,“.*”表示包下所有的类,而“..*”表示包,子孙包下的所有类.
execution(* com.smart.*(..)):匹配com.smart包下的所有类的所有方法.
execution(* com.smart..*(..)):匹配com.smart包.子孙包下所有的类的所有方法.
execution(* com..*.*Dao.find*(..)):匹配包名前缀为com的任何包下类名后缀为Dao的方法,方法名必须以find为前缀.如:com.smart.UserDao#findByUserId(), com.smart.dao.ForumDao#findById()等.
(4):通过方法入参定义切点:
切点表达式中的方法入参部分比较复杂,可以使用“*”,“..”通配符.其中“*”表示任意类型的参数;而“..”表示任意类型的参数且参数个数不限.
execution(* joke(String,int)):匹配joke(String str,int d)方法.
execution(* joke(String,*):匹配目标类中的joke(),但该方法的第一个入参为String类型,第二个入参可以是任意类型.
execution(* joke(String,..)):匹配目标类中的joke(),该方法的第一个入参为String类型,后面可以有任意个入参,且入参类型不受限制.
execution(* joke(Object+)):匹配目标类中的joke(),方法拥有一个入参,且入参是Object类型或该类的子类.
[3]:args()和@args()
args():该函数接收一个类名,表示目标类方法入参对象是指定类(包含字类)时,切点匹配
1):args(com.smart.Waiter)表示运行时入参是Waiter类型的方法, 其等价于execution(* *(com.smart.Waiter+))当然也等价于args(com.smart.Waiter+).
2):@args() 太啰嗦,不打字了...
[4]:within()
通过类匹配模式串声明切点,within()函数定义的连接点是针对目标类而言的,而非针对运行期对象的类型而言,这一点和execution()是相同的.但和execution()函数不同的是,within()所指定的连接点的最小范围只能是类,二execution()所指定的连接点可以大到包,小到方法入参.所以从某种意义上说,execution()函数的功能涵盖了within()函数的功能.within()函数语法如下:
within(<类匹配模式>)
within(com.smart.NativeWaiter):匹配目标类NativeWaiter的所有方法.
within(com.smart.*):匹配com.smart包中的所有类,但不包括子孙包,所以com.smart.service包中类的方法不匹配这个切点
within(co.smart..*):匹配com.smart包及子孙包中的类,所以com.smart.service,com.smart.dao,com.smart.service.forum等包中的所有类都匹配这个切点.
[5]@within() ,@target()
[6]target(),this()
来源:https://www.cnblogs.com/xibushijie/p/12846042.html
猜你喜欢
- 排列组合是常见的数学问题,本文就以完整实例形式讲述了C#实现排列组合算法的方法。分享给大家供大家参考之用。具体方法如下:首先,数学中排列组合
- 说明本项目采用 maven 结构,主要演示了 spring mvc + mybatis,controller 获取数据后以json 格式返回
- 走马灯是一种常见的效果,本文讲一下如何用 PageView 在 Flutter 里实现一个走马灯, 效果如下,当前页面的高度比其它页面高,切
- aes 对称加密密钥必须是32字节using System;using System.Security.Cryptography;using
- 前言前几天有个需求,需要使用不同的数据源,例如某业务要用A数据源,另一个业务要用B数据源。我上网收集了一些资料整合了一下,虽然最后这个需求不
- Java基于对象流实现银行系统的具体代码,供大家参考,具体内容如下系统特点:数据持久化到文件中,系统启动后,加载文件中数据到集合中,相当于做
- 这篇文章主要介绍了JavaWeb如何实现禁用浏览器缓存,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋
- 一、需要导入的jar1.commons-collections4-4.1.jar2.poi-3.17-beta1.jar3.poi-ooxm
- 首先什么是注解?@Override就是注解,它的作用是:1、检查是否正确的重写了父类中的方法。 2、标明代码,这是一个重写的方法。1、体现在
- 如果在类路径上添加了Spring Boot Security依赖项,则Spring Boot应用程序会自动为所有HTTP端点提供基本身份验证
- 接收从控制台输入的数据可以使用Scanner类实现,Scanner类在一个名为util的包中需要在程序中导入这个包, 即在程序中添加impo
- Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spri
- java使用贪心算法解决电台覆盖问题代码实现/** * 贪心算法实现集合覆盖 */public class Demo { &n
- 本文实例讲述了Java基于链表实现栈的方法。分享给大家供大家参考,具体如下:在上几小节中我们实现了基本的链表结构,并在上一节的底部给出了有关
- 前言Android提供了很多种保存应用程序数据的方法。其中一种就是用SharedPreferences对象来保存我们私有的键值(key-va
- 🍅1.注解JUnit提供了非常强大的注解功能,通过@Test注解修饰到方法上,该方法就变为了一个测试方法,执行当前类时,会自动的执行该类下所
- 作为Android基础组件之一,大家对viewpager已经很熟悉了,网上也有很多使用viewpager来加载图片的案例。但是像微信那样点击
- 这篇文章首先介绍了在SpringBoot中如何获得项目的编译时间和版本号,并向外提供接口,然后介绍了介绍了新版maven获得时间戳时区错误的
- 快速排序过程没有既不浪费空间又可以快一点的排序算法呢?那就是“快速排序”!光听这个名字是不是就觉得很高端呢。假设我们现在对“52 39 67
- 实现需求:两个线程交替打印1,0,打印10轮java多线程口诀:高内聚,低耦合线程操作资源类判断干活通知防止虚假唤醒方式一:使用synchr