详解原生Spring框架下的类切入点表达式与切入点函数

2023-12-02 19:45

本文主要是介绍详解原生Spring框架下的类切入点表达式与切入点函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

 😉😉 学习交流群:

✅✅1:这是孙哥suns给大家的福利!

✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料

🥭🥭3:QQ群:583783824   📚📚  工作微信:BigTreeJava 拉你进微信群,免费领取!

🍎🍎4:本文章内容出自上述:Spring应用课程!💞💞

💞💞5:以上内容,进群免费领取呦~ 💞💞💞💞

一:类切入点表达式概念

        假设我需要把一个类当中的所有的方法定义为切入点,这样我们可以使用这个类切入点,类切入点指定类为切入点,只不过是这样的一个称呼。
        所有的额外功能还是加在了这个类的全部的方法上,这样的形式是包+类:
        详细的切入点配置如下,测试结果不贴出来了,和其他的一样没啥区别。

1:某一个确定类加入额外功能

        * com.aaa.bbb.impl.*(..)  :类中的所有方法都加入了额外功能,这是第一种语法形式。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="userService" class = "com.pactera.spring.proxy.UserServiceImpl"/><bean id="orderService" class = "com.pactera.spring.proxy.OrderServiceImpl"/>
<!--    <bean id="before" class="com.pactera.spring.dynamic.Before"/>--><bean id = "around" class = "com.pactera.spring.dynamic.Around"/><aop:config><!--这个标签就是用来定义切入点的,expression这个是切入点表达式,代表所有的方法都要加上这个额外功能--><!--所有的方法,都作为切入点作为额外功能。--><aop:pointcut id="pc" expression="execution(* com.pactera.spring.proxy.UserServiceImpl.*(String,..))"/><!--组装,组长的目的就是为了把切入点与额外的功能进行整合--><aop:advisor advice-ref="around" pointcut-ref="pc"/></aop:config>
</beans>

        指定特定类作为切入点,额外功能加入的自然这个类当中的所有的方法都会加上对应的额外功能的。

2:不同包下的同名的类作为类切入点

* *.UserServiceImpl.*(..) -->这样写是不可以的,一个*只能匹配一级包,一般我们的类不会写在com包下的,这样写是有问题的。

如果是多级包应该是这样写:*..表达的就是一级包乃至多级包。* *..UserServiceImpl.*(..):这样写就能匹配多级目录下的这个类了。任何包下的这个类都作为切入点。

3:某个包下的所有的方法作为切入点

我想为所有的某个包下的所有的方法添加切入点:

* com.alibaba.a.*.*(..) -->匹配这个包下的所有类的所有的方法。
注意上边这样写只能在a的包下,不能在a的子包下,子包下是不能被匹配到的。
* com.alibaba..a.*.*(..) -->匹配a包,包括a子包下的所有的类。

将来我们的使用切入点的时候,包的切入点的使用价值更高。使用更加频繁

二:切入点函数

        切入点函数的作用就是用执行切入点表达式的函数        
        excution:最为重要的一个切入点函数,也是功能最全的。执行方法切入点表达式,也可以执行类切入点表达式,也可以执行包切入点表达式
        弊端:excution执行切入点表达式的时候,书写麻烦,比如:execution(* com.alibaba.proxy..*.*(..);这样写起来很麻烦,spring为我们提供了其他的切入点函数,其他的切入点函数只是起到了简化execution切入点函数的作用,功能还是一样的的,本质上是没有任何区别的,简化的事execution书写的复杂度,但是功能上是完全一致的。

1:args函数

        作用:主要用于函数(方法的)参数的匹配,我们研究下这个意思。

        需求1:方法的切入点其他我不关系,参数必须是两个String的方法作为切入点

        execution(* *(String,String)) -->使用excution这样写
        args(String,String) -->使用args这样写。
        代码和测试结果如下:

    <aop:config><!--这个标签就是用来定义切入点的,expression这个是切入点表达式,代表所有的方法都要加上这个额外功能--><!--所有的方法,都作为切入点作为额外功能。-->
<!--        <aop:pointcut id="pc" expression="execution(* com.pactera.spring.proxy.UserServiceImpl.*(String,..))"/>    --><aop:pointcut id="pc" expression="args(String,String))"/><!--组装,组长的目的就是为了把切入点与额外的功能进行整合--><aop:advisor advice-ref="around" pointcut-ref="pc"/></aop:config>

        测试执行结果: 

    /** @Target: 用于测试* login(String,String)这个切入点表达式_测试多个切入点表达形式* @Author: DaShu* @Date: 2021/6/21 20:53* @Result: 这个切入点定义到了login方法,并且具有两个参数,并且两个参数都是String类型;*/@Testpublic void test6(){ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext3.xml");UserService userService = (UserService)ctx.getBean("userService");userService.login("zhangjie","zhangjie");//...........................这里是额外功能...............................//UserServiceImpl.login//-------------------------------这里还是额外功能----------------------------------------}

2:whthin这个函数

        作用:主要用于类、包切入点的表达式的匹配。

        需求:切入点想选择UserServiceImpl这一个类,不关心包
        execution(* *..UserService.*(..)) -->使用execution方式这样写。
        within(*..UserServiceImpl) -->这个不关系包只关心类的书写方法。
        execution(* com.baizhiedu.proxy..*.*(..)) --使用execution这样写。
        within(com.baizhiedu.proxy..*)
        其实这种简化的写法就是在execution函数选择了一些东西,省略了一些东西。

3:@Annotation

        作用:为具有特定注解的方法加入额外功能,这个是最核心的功能

    <aop:config><!--这个标签就是用来定义切入点的,expression这个是切入点表达式,代表所有的方法都要加上这个额外功能--><!--所有的方法,都作为切入点作为额外功能。-->
<!--        <aop:pointcut id="pc" expression="execution(* com.pactera.spring.proxy.UserServiceImpl.*(String,..))"/>    --><aop:pointcut id="pc" expression="@annotation(com.pactera.spring.annotation.Log)"/><!--组装,组长的目的就是为了把切入点与额外的功能进行整合--><aop:advisor advice-ref="around" pointcut-ref="pc"/></aop:config>
/*** @Auther: DaShu* @Date: 2021/6/15 18:58* @Description:*/
public class UserServiceImpl implements UserService{@Override@Logpublic void register(User user) {//这代表的事业务运算+dao的调用,额外功能不写在这里边。System.out.println("UserServiceImpl.register");}@Overridepublic boolean login(String name,String password) {System.out.println("UserServiceImpl.login");return true;}
}

三:切入点函数的逻辑运算

        切入点函数的逻辑运算值得是整合多个切入点函数一起配合工作,进而完成更为复杂的需求
逻辑运算指的就是整合多个切入点函数的,让他们一起起作用,进而满足可能会遇到的更为复杂的需求,基本操作

1:and  与操作

        案例1:方法得叫login,方法参数参数是两个String类型即可。
        execution(* login(String,String))  -->使用原生execution的书写方式
        execution(* login(..))  and  args(String,String)  --使用切入点函数的逻辑运算。
        两个表达式必须同时满足,两者取的是交集

        注意:与操作不能用于同种类型的切入点函数!

2:or  或操作

        两个切入点满足之一即可进行。

3:!非操作

    <aop:config>
<!--        <aop:pointcut id="pc" expression="@annotation(com.spring.annotation.Log) "/>--><aop:pointcut id="pc" expression="@annotation(com.spring.annotation.Log) and !execution(* com.spring.proxy.UserServiceImpl.re*(..))"/><aop:pointcut id="pc01" expression="@annotation(com.spring.annotation.Log) and !execution(* com.spring.proxy.UserServiceImpl.register(..))"/><aop:advisor advice-ref="around" pointcut-ref="pc"/></aop:config>
    @Testpublic void test1() {ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");UserService userService = (UserService) ctx.getBean("userService");userService.register(new User());userService.register01(new User());//UserServiceImpl.register//UserServiceImpl.register01}@Testpublic void test2() {ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");UserService userService = (UserService) ctx.getBean("userService");userService.login("sun", "123456");//...........................这里是额外功能1...............................//UserServiceImpl.login//-------------------------------这里还是外功能2----------------------------------------}

这个非操作使用的是!这个符号。

四:Spring动态代理开发总结

        为什么使用Spring动态代理开发?

        动态代理开发就是代理开发,作用就是通过代理类对目标类或者叫做原始类增加额外的功能,好处就利于原始类的维护,这里代理类的好处,具体到Spring的动态代理的来讲呢,一共是四步,Spring创建目标对象,Spring创建额外功能对象,定义切入点,整合切入点和额外功能。

这篇关于详解原生Spring框架下的类切入点表达式与切入点函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/446572

相关文章

Spring WebClient从入门到精通

《SpringWebClient从入门到精通》本文详解SpringWebClient非阻塞响应式特性及优势,涵盖核心API、实战应用与性能优化,对比RestTemplate,为微服务通信提供高效解决... 目录一、WebClient 概述1.1 为什么选择 WebClient?1.2 WebClient 与

idea的终端(Terminal)cmd的命令换成linux的命令详解

《idea的终端(Terminal)cmd的命令换成linux的命令详解》本文介绍IDEA配置Git的步骤:安装Git、修改终端设置并重启IDEA,强调顺序,作为个人经验分享,希望提供参考并支持脚本之... 目录一编程、设置前二、前置条件三、android设置四、设置后总结一、php设置前二、前置条件

Java.lang.InterruptedException被中止异常的原因及解决方案

《Java.lang.InterruptedException被中止异常的原因及解决方案》Java.lang.InterruptedException是线程被中断时抛出的异常,用于协作停止执行,常见于... 目录报错问题报错原因解决方法Java.lang.InterruptedException 是 Jav

深入浅出SpringBoot WebSocket构建实时应用全面指南

《深入浅出SpringBootWebSocket构建实时应用全面指南》WebSocket是一种在单个TCP连接上进行全双工通信的协议,这篇文章主要为大家详细介绍了SpringBoot如何集成WebS... 目录前言为什么需要 WebSocketWebSocket 是什么Spring Boot 如何简化 We

java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)

《java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)》:本文主要介绍java中pdf模版填充表单踩坑的相关资料,OpenPDF、iText、PDFBox是三... 目录准备Pdf模版方法1:itextpdf7填充表单(1)加入依赖(2)代码(3)遇到的问题方法2:pd

Java Stream流之GroupBy的用法及应用场景

《JavaStream流之GroupBy的用法及应用场景》本教程将详细介绍如何在Java中使用Stream流的groupby方法,包括基本用法和一些常见的实际应用场景,感兴趣的朋友一起看看吧... 目录Java Stream流之GroupBy的用法1. 前言2. 基础概念什么是 GroupBy?Stream

python中列表应用和扩展性实用详解

《python中列表应用和扩展性实用详解》文章介绍了Python列表的核心特性:有序数据集合,用[]定义,元素类型可不同,支持迭代、循环、切片,可执行增删改查、排序、推导式及嵌套操作,是常用的数据处理... 目录1、列表定义2、格式3、列表是可迭代对象4、列表的常见操作总结1、列表定义是处理一组有序项目的

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

SpringBoot监控API请求耗时的6中解决解决方案

《SpringBoot监控API请求耗时的6中解决解决方案》本文介绍SpringBoot中记录API请求耗时的6种方案,包括手动埋点、AOP切面、拦截器、Filter、事件监听、Micrometer+... 目录1. 简介2.实战案例2.1 手动记录2.2 自定义AOP记录2.3 拦截器技术2.4 使用Fi