Spring 从入门到精通 (十四) 切入点详解
关键词:Spring | 切入点 | 详解
本专栏通过理论和实践相结合,系统学习框架核心思想及简单原理,原创不易,如果觉得文章对你有帮助,点赞收藏支持博主 ✨
一、切入点表达式和方法
切入点表达式的语法和方法的结构是一一对应的
从上图不难看出,为什么所有方法的切入点表达式要写成 * *(..)
二、练习
2.1、只有 login 方法会被切中
expression="execution(* login(..))"
- 1
测试:
可以看到 login 方法被代理了,而 register 方法没有
----开启事务----
UserServiceImpl login + DAO
----提交事务----
UserServiceImpl register + DAO
- 1
- 2
- 3
- 4
2.2、两个参数都是 String 类型的方法才会被切中
expression="execution(* *(String,String))"
- 1
测试:
因为 login 方法的两个参数都是 String 类型,满足要求,被切中代理了,而 register 方法的参数是一个 User 对象,不满足要求
----开启事务----
UserServiceImpl login + DAO
----提交事务----
UserServiceImpl register + DAO
- 1
- 2
- 3
- 4
2.3、参数类型是User类型的方法会被切中
expression="execution(* *(com.liu.entity.User))"
- 1
注意: User参数不是 java.lang
包下的,因此必须写入类全限定名
测试:
这次应该是 register 被切中了,因为它的参数类型是 User
UserServiceImpl login + DAO
----开启事务----
UserServiceImpl register + DAO
----提交事务----
- 1
- 2
- 3
- 4
2.4、连用…,中间使用逗号分隔
expression="execution(* *(String,..))"
- 1
这个意思就是修饰符返回值任意,方法名字任意,第一个参数必须是 String 类型,后面的参数有几个都可以,类型是什么都可以,只要满足上面的条件就会被切中,分析满足条件的只有 login 方法了
测试:
----开启事务----
UserServiceImpl login + DAO
----提交事务----
UserServiceImpl register + DAO
- 1
- 2
- 3
- 4
三、问题
我们发现其实这个表达式很简单,很实用,但是现在的写法有个很致命的问题,切的范围不准确,只是在方法级别,假如不同的包,我需要切中某包下的这个方法,应该怎么做呢?
下面就继续深入学习切入点表达式,加油!
四、精确切入
其实很简单,上面的方法其实是一种简写,我们想要切中某个包下的类中的方法,无非就从包开始限定就可以了
修饰符 返回值 包.类.方法(参数)
-
execution(* com.liu.service.*.*(..))
包:com.liu.service
类:任意类
方法:任意方法
参数:任意参数
返回值:任意返回值类型 -
execution(String com.liu.service.*ServiceImpl.*(..))
包:com.liu.service
类:以ServiceImpl结尾的类
方法:任意方法名
参数:任意
返回值:必须是String类型相关方法 -
execution(String com.liu.service.*Service*.*(String))
包:com.liu.service
类:类名中包含Service关键字的类
方法:任意
参数:参数只有一个,类型必须是String类型
返回值:返回值必须是String -
execution(* com.liu.service..*.*(..))
包:com.liu.service以及下面的所有子包
类:任意类
方法:任意方法
参数:任意参数
返回值:任意类型 -
execution(* com.liu.service.*ServiceImpl.*(..))
包:com.liu.service
类:以ServiceImpl结尾的类
方法:任意方法名
参数:任意
返回值:任意类型 -
execution(* *(..))
避免使用
包:项目中所有包
类:项目中所有类
方法:所有方法
参数:所有参数
返回值:任意参数
五、切入点函数
用于执行切入点表达式
Spring提供了很多切入点函数,用于不同的场景,可以一定程度上简化一些配置
5.1、execution()
前面已经学过了,最重要的一个,其他函数能实现的它都能实现,不好的地方就是书写必须很全。
5.2、args()
关注点:主要用于函数(方法)参数的匹配
举例: 必须是两个String类型参数的方法,其他的包啊类啊我不关心,这时就可以使用
expression="args(String,String)"
- 1
不出意外,应该是 login 方法被切中了
测试:
----开启事务----
UserServiceImpl login + DAO
----提交事务----
UserServiceImpl register + DAO
- 1
- 2
- 3
- 4
5.3、within()
关注点:主要用于关注类,包的切入点,不关心方法修饰符,返回值以及参数
举例: com.liu.Service.UserServiceImpl
包下的所有方法都被切中
expression="within(com.liu.service.UserServiceImpl)"
- 1
不出意外,UserServiceImpl
包下的所有方法,也就是 login 和 register 方法被切中了
测试:
----开启事务----
UserServiceImpl login + DAO
----提交事务----
----开启事务----
UserServiceImpl register + DAO
----提交事务----
- 1
- 2
- 3
- 4
- 5
- 6
5.3、@annotation()
自定义注解并使用时,可以使用@annotation()去查找哪些类或方法使用了这个注解,并添加额外功能
首先自定义注解 MyAffair,意思是我们自定义的事务注解
MyAffair
// 注解作用目标 在方法上使用
@Target(ElementType.METHOD)
// 注解执行时机 运行时才有用
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAffair {
}
- 1
- 2
- 3
- 4
- 5
- 6
然后在 UserServiceImpl
类方法上使用此注解
public class UserServiceImpl implements UserService{
@Override
@MyAffair
public void register(User user) {
System.out.println("UserServiceImpl register + DAO");
}
@Override
@MyAffair
public boolean login(String name, String pwd1) {
System.out.println("UserServiceImpl login + DAO");
return true;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
表达式
注意:此时使用的切入点函数为@annotation
,表达式写的就是我们自定义注解的全包名。
expression="@annotation(com.liu.MyAffair)"
- 1
此时,启动程序,切入点表达式发现你使用自定义注解的方式,就去查找添加了自定义注解的方法,并全部添加额外功能
测试:
----开启事务----
UserServiceImpl login + DAO
----提交事务----
----开启事务----
UserServiceImpl register + DAO
----提交事务----
- 1
- 2
- 3
- 4
- 5
- 6
六、切入点函数逻辑运算
整合多个切入点函数,从而完成更为复杂的需求
6.1、and与
假设要切中 login 方法,同时方法参数为两个字符串
-- 之前
execution(* login(String,String))
-- 之后
execution(* login(..)) and args(String,String)
- 1
- 2
- 3
- 4
注意: 与操作不能用于同种类型的切入点函数,比如
execution(* login(..)) and execution(* register(..))
- 1
这根本就不存在
6.1、or或
execution(* login(..)) or execution(* register(..))
- 1
login 或 register 都可以
七、写在最后
座右铭:不要在乎别人如何看你,要在乎你自己如何看未来,看梦想,看世界…!
一起学习的可以私信博主或添加博主微信哦。
文章来源: blog.csdn.net,作者:王子周棋洛,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/m0_53321320/article/details/125947980
- 点赞
- 收藏
- 关注作者
评论(0)