详解原生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

相关文章

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

详解C#如何提取PDF文档中的图片

《详解C#如何提取PDF文档中的图片》提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使用,下面我们就来看看如何使用C#通过代码从PDF文档中提取图片吧... 当 PDF 文件中包含有价值的图片,如艺术画作、设计素材、报告图表等,提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使

Kotlin 作用域函数apply、let、run、with、also使用指南

《Kotlin作用域函数apply、let、run、with、also使用指南》在Kotlin开发中,作用域函数(ScopeFunctions)是一组能让代码更简洁、更函数式的高阶函数,本文将... 目录一、引言:为什么需要作用域函数?二、作用域函China编程数详解1. apply:对象配置的 “流式构建器”最

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

Java中List的contains()方法的使用小结

《Java中List的contains()方法的使用小结》List的contains()方法用于检查列表中是否包含指定的元素,借助equals()方法进行判断,下面就来介绍Java中List的c... 目录详细展开1. 方法签名2. 工作原理3. 使用示例4. 注意事项总结结论:List 的 contain

Android中Dialog的使用详解

《Android中Dialog的使用详解》Dialog(对话框)是Android中常用的UI组件,用于临时显示重要信息或获取用户输入,本文给大家介绍Android中Dialog的使用,感兴趣的朋友一起... 目录android中Dialog的使用详解1. 基本Dialog类型1.1 AlertDialog(

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("