SpringAOP中切入点的高级使用
SpringAOP中切点的高级使用
一、使用控制流切入点(ControlFlowPointcut)
什么是控制流切入点呢?看下面的代码(为了方便,就写进了一个公共类)
class Cat {
public void talk() {
System.out.println("I am a cat");
}
public void play() {
System.out.println("I am palying");
}
}
class BlackCat {
public void sleep(Cat cat) {
cat.play();
System.out.println("I am a blackCat , I am sleeping");
}
}
/**
* 创建前置通知类
*/
class BeforeAdvice implements MethodBeforeAdvice{
@Override
public void before(Method method, Object[] objects, @Nullable Object o) throws Throwable {
System.out.println("这个方法被通知了"+method);
}
}
- 需求:我们要给Cat的play()方法进行通知,但是呢,并不是说在调用play()方法的任何时候都通知, 只要在blackCat的sleep()方法中调用play()方法时才通知,也就是说:
public static void main(String[] args) {
Cat cat = new Cat();
cat.play();//这个调用不会被通知
BlackCat blackCat = new BlackCat();
blackCat.sleep(cat);//这个方法中调用的paly方法才会被通知
}
创建一个ControlFlowPointcut的切入点
public static void main(String[] args) {
// Cat cat = new Cat();
// cat.play();//这个调用不会被通知
//
// BlackCat blackCat = new BlackCat();
// blackCat.sleep(cat);//这个方法中调用的paly方法才会被通知
Cat target = new Cat();
//第一个参数是当前就是的执行要被通知的方法的类,第二个就是的执行要被通知的方法的方法名
Pointcut pc = new ControlFlowPointcut(BlackCat.class, "sleep");
Advisor advisor = new DefaultPointcutAdvisor(pc, new BeforeAdvice());
ProxyFactory proxy = new ProxyFactory();
proxy.setTarget(target);
proxy.addAdvisor(advisor);
Cat proxyCat = (Cat) proxy.getProxy();
proxyCat.play();//这个方法不会被通知
System.out.println("----------------");
BlackCat blackCat = new BlackCat();
blackCat.sleep(proxyCat);//这个方法中调用的paly方法才会被通知
}

二、使用组合切入点(ComposablePointcut)
所谓组合切入点就是利用逻辑关系(or 和 and)来对切入点进行组合,比如上一文中说过的那几种切入点,使用逻辑关系写在一起就可以了。但是并不是直接和切入点来组合,而是组合切入点中的
ClassFilter和MethodMatcher(为什么是这样?在这篇文章看一下Pointcut类的源码,就明白了)
用法:
ComposablePointcut的union()表示“或”
ComposablePointcut的intersection()表示“和”先定义三个MethodMatcher类
/**
* 匹配sleep方法名
*/
class SleepMethodMatcher extends StaticMethodMatcher{
@Override
public boolean matches(Method method, Class<?> aClass) {
return method.getName().equals("sleep");
}
}
/**
* 匹配s开头
*/
class SStartMethodMatcher extends StaticMethodMatcher{
@Override
public boolean matches(Method method, Class<?> aClass) {
return method.getName().startsWith("s");
}
}
/**
* 匹配k结尾
*/
class KEndMethodMatcher extends StaticMethodMatcher{
@Override
public boolean matches(Method method, Class<?> aClass) {
return method.getName().endsWith("k");
}
}
- 创建切入点
/**
* 创建前置通知类
*/
class BeforeAdviceDemo implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] objects, @Nullable Object o) throws Throwable {
System.out.println("这个方法被通知了" + method);
}
}
- 测试类
public static void main(String[] args) {
Cat target = new Cat();
//这个构造方法要传入的是一个classFilter和methodMatcher实例
ComposablePointcut pc = new ComposablePointcut(ClassFilter.TRUE, new KEndMethodMatcher());
// pc.union(new SStartMethodMatcher());//匹配s开头的方法,和上边的切点是或的关系
// pc.intersection(new SleepMethodMatcher()); //匹配sleep方法,和上边切点是和的关系
Advisor advisor = new DefaultPointcutAdvisor(pc,new BeforeAdviceDemo());
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
proxyFactory.addAdvisor(advisor);
Cat cat = (Cat) proxyFactory.getProxy();
cat.talk();
}
上边的这个ClassFilter.TRUE 和下边代码其实是一样的,意思就是返回的classFilter为true,也就是匹配所有类
new ClassFilter() {
@Override
public boolean matches(Class<?> aClass) {
return true;
}
}
SpringAOP中切入点的高级使用的更多相关文章
- SpringAop中JoinPoint对象
来自:http://blog.csdn.net/it_zouxiang/article/details/52576917 JoinPoint的用法 JoinPoint 对象 JoinPoint对象封装 ...
- 在MySQL中实现Rank高级排名函数【转】
MySQL中没有Rank排名函数,当我们需要查询排名时,只能使用MySQL数据库中的基本查询语句来查询普通排名.尽管如此,可不要小瞧基础而简单的查询语句,我们可以利用其来达到Rank函数一样的高级排名 ...
- 详解Vue中watch的高级用法
我们通过实例代码给大家分享了Vue中watch的高级用法,对此知识点有需要的朋友可以跟着学习下. 假设有如下代码: <div> <p>FullName: {{fullName} ...
- 在MySQL中实现Rank高级排名函数
MySQL中没有Rank排名函数,当我们需要查询排名时,只能使用MySQL数据库中的基本查询语句来查询普通排名.尽管如此,可不要小瞧基础而简单的查询语句,我们可以利用其来达到Rank函数一样的高级排名 ...
- Expo大作战(二十三)--expo中expo kit 高级属性(没干货)
简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...
- SpringAOP中的注解配置
使用注解实现SpringAOP的功能: 例子: //表示这是被注入Spring容器中的 @Component //表示这是个切面类 @Aspect public class AnnotationHan ...
- ActiveMQ中的Destination高级特性(一)
---------------------------------------------------------------------------------------- Destination ...
- linux中find命令高级用法
前言 在<Linux中的文件查找技巧>一文中,我们已经知道了文件查找的基本方法,今天我们介绍find命令的一些高级使用技巧.它能满足我们一些更加复杂的需求. 查找空文件或空目录 有时候需要 ...
- C#中的多线程 - 高级多线程 z
原文:http://www.albahari.com/threading/part4.aspx 专题:C#中的多线程 1非阻塞同步Permalink 之前,我们描述了即使是很简单的赋值或更新一个字段也 ...
随机推荐
- 【限时免费】从入门到实战,5节课玩转Kafka!赢音箱、书籍好礼!
欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),输入关键字"加群",加入华为云线上技术讨论群:输入关键字"最新活动",获取华 ...
- Nginx 404 Not Found 解决办法
环境:宝塔Nginx面板 解决办法: 宝塔面板--站点设置-配置文件. 去掉: error_page 404 /404.html; 前面的 # 号.
- DRF Django REST framework 之 视图组件(四)
引言 在我们有几十上百的视图类,都有get,post等方法,在功能类似时,会导致大量的重复代码出现,显然还有很多可以优化的地方.这也就有了视图组件,它的功能非常强大,能很好的优化接口逻辑. 视图组件 ...
- mac端口占用
lsof -i tcp:port 可以查看该端口被什么程序占用,并显示PID port 替换成端口号, eg: lsof -i tcp:8081 kill pid 杀死PID
- Springboot结合Redis
安装 Redis 安装 gcc Yum install gcc-c++ 解压 redis.3.0.0.tar.gz 压缩包 tar -zxvf redis-3.0.0.tar.gz 进入解压后的目 ...
- 数据库Oracle 数字,字符,日期之间的相互转换
数据类型转换分为俩种 . 隐式数据类型转换:当源数据的类型和目标数据的类型不同的时候,如果没有转换函数,就会发生隐式转换,也称自动转换. 对于直接赋值转换: 对于表达式赋值: 隐式转换的问题: 性能 ...
- 大数据之Linux用户权限设置
用户 是Linux系统工作中重要的一环, 用户管理包括 用户 与 组 管理,在Linux系统中, 不论是由本级或是远程登录系统, 每个系统都必须拥有一个账号, 并且对于不同的系统资源拥有不同的使用权限 ...
- 2019牛客全国多校训练四 I题 string (SAM+PAM)
链接:https://ac.nowcoder.com/acm/contest/884/I来源:牛客网 题目描述 We call a,ba,ba,b non-equivalent if and only ...
- CodeForces1006F-Xor-Paths
F. Xor-Paths time limit per test 3 seconds memory limit per test 256 megabytes input standard input ...
- 《项目实战》从Spring开始说起
引导 从今天开始,我们正式进入项目实战系列,我们会从项目架构的搭建,以及如何解决三高问题(高并发.高可用.高性能),源码会同步进行更新,欢迎大家持续关注 https://gitee.com/liupa ...