上一篇 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;
}
}

本项目代码地址,觉得写的还不错就给个star

SpringAOP中切入点的高级使用的更多相关文章

  1. SpringAop中JoinPoint对象

    来自:http://blog.csdn.net/it_zouxiang/article/details/52576917 JoinPoint的用法 JoinPoint 对象 JoinPoint对象封装 ...

  2. 在MySQL中实现Rank高级排名函数【转】

    MySQL中没有Rank排名函数,当我们需要查询排名时,只能使用MySQL数据库中的基本查询语句来查询普通排名.尽管如此,可不要小瞧基础而简单的查询语句,我们可以利用其来达到Rank函数一样的高级排名 ...

  3. 详解Vue中watch的高级用法

    我们通过实例代码给大家分享了Vue中watch的高级用法,对此知识点有需要的朋友可以跟着学习下. 假设有如下代码: <div> <p>FullName: {{fullName} ...

  4. 在MySQL中实现Rank高级排名函数

    MySQL中没有Rank排名函数,当我们需要查询排名时,只能使用MySQL数据库中的基本查询语句来查询普通排名.尽管如此,可不要小瞧基础而简单的查询语句,我们可以利用其来达到Rank函数一样的高级排名 ...

  5. Expo大作战(二十三)--expo中expo kit 高级属性(没干货)

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  6. SpringAOP中的注解配置

    使用注解实现SpringAOP的功能: 例子: //表示这是被注入Spring容器中的 @Component //表示这是个切面类 @Aspect public class AnnotationHan ...

  7. ActiveMQ中的Destination高级特性(一)

    ---------------------------------------------------------------------------------------- Destination ...

  8. linux中find命令高级用法

    前言 在<Linux中的文件查找技巧>一文中,我们已经知道了文件查找的基本方法,今天我们介绍find命令的一些高级使用技巧.它能满足我们一些更加复杂的需求. 查找空文件或空目录 有时候需要 ...

  9. C#中的多线程 - 高级多线程 z

    原文:http://www.albahari.com/threading/part4.aspx 专题:C#中的多线程 1非阻塞同步Permalink 之前,我们描述了即使是很简单的赋值或更新一个字段也 ...

随机推荐

  1. 机器学习实战书-第二章K-近邻算法笔记

    本章介绍第一个机器学习算法:A-近邻算法,它非常有效而且易于掌握.首先,我们将探讨女-近邻算法的基本理论,以及如何使用距离测量的方法分类物品:其次我们将使用?7««^从文本文件中导人并解析数据: 再次 ...

  2. Windows下创建Python虚拟环境的两种方法:

    在实际的项目开发中,我们会根据自己的需求去下载各种相应的框架库,但是每个项目可能使用的库不一样,或者版本不一样等等等.为了避免这些因素对我们的项目造成一些不必要的影响,我们可能需要来回的切换或者装卸等 ...

  3. MVC异常处理

    处理局部异常 控制器: @Controller @RequestMapping("/ex") public class ExceptionController { @Excepti ...

  4. UESTC1961-咸鱼睡觉觉

    咸鱼睡觉觉 Time Limit: 1000 MS     Memory Limit: 64 MB Submit Status 咸鱼要睡觉觉了! 但那群咕咕有点烦. 咸鱼决定要赶走一些咕咕,使得他们不 ...

  5. 纯手工搭建K8s(单节点)

    准备说明: 因为为纯手动搭建,所以针对安装时需要的一些安装包需提前下载好 cfssl_linux-amd64. cfssljson_linux-amd64. cfssl-certinfo_linux- ...

  6. 深入理解 Java 泛型

  7. Day 01 Markdown基本语法

    目录 Markdown基本语法 标题 一级标题 二级标题 三级标题 加粗 斜体 高亮 上标 下标 代码引用(>式) 代码引用(```式) 代码引入(`式) 插入链接(链接显示) 插入链接(链接描 ...

  8. Python流程控制之循环结构

    目录 while循环 for循环 嵌套循环 break.continue.pass 练习 当出现有规律或者是重复的事情就可以使用循环. 1.循环变量初始化 2.循环条件 3.循环体 4.改变循环变量 ...

  9. 【MYSQL】安装MySQL端口被占用

    出现问题: 安装mysql时,发现端口被占用 解决方法: 方法一: 修改端口号:3308,3309等都可以 方法二: 按键盘"win+r" → 打开 cmd → 输入netstat ...

  10. Vue单页面应用打包app处理返回按钮

    情况 顶部返回,在header.vue公用组件中使用 this.$router.go(-1) 安卓:点击返回按钮:登录页,项目选择页,首页等几个一级页面要求提示用户是否退出app;确定,退出;取消:不 ...