上一篇 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. 腾讯视频缓存 tdl 转 mp4

    找到腾讯视频->设置,看下缓存文件的目录地址,然后cmd,通过命令进行转化.  copy/b *.tdl 1.mp4

  2. solr 的安装和配置

    Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口.用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引:也可以通过Http Get操 ...

  3. 【开发者portal在线开发插件系列二】多条上下行消息(messageId的使用)【华为云技术分享】

    前言和基本操作请参考[开发者portal在线开发插件系列一]profile和基本上下行消息,此处不再复述,没操作过的小伙伴一定要先去看看哦~ 话不多说,开始今天的演(表)示(演) 场景说明: 假设一: ...

  4. Python常用转义字符

    \   在行尾时是     续行符 \\   反斜杠符号 \' 单引号 \"  双引号 \a  响铃 \b  退格 \e  转义 \000  空 \n     换行 \v 纵向制表符 \t  ...

  5. 16.Django学习之文件上传和下载

    上传就这么六步! 一. settings配置文件中配置 MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'medias').repl ...

  6. HDU-6113

    度度熊是一个喜欢计算机的孩子,在计算机的世界中,所有事物实际上都只由0和1组成. 现在给你一个n*m的图像,你需要分辨他究竟是0,还是1,或者两者均不是. 图像0的定义:存在1字符且1字符只能是由一个 ...

  7. 【MobX】MobX 简单入门教程

    一.MobX 介绍 首先看下官网介绍: MobX 是一个经过战火洗礼的库,它通过透明的函数响应式编程(transparently applying functional reactive progra ...

  8. Nginx(四)-- Nginx的扩展-OpenRestry

    1. OpenResty 安装及使用 OpenResty 是一个通过 Lua 扩展 Nginx 实现的可伸缩的 Web 平台,内部集成了大量精良的 Lua 库.第三方模块以及大多数的依赖项.用于方便地 ...

  9. 支持100+业务线、累计发布17万次|宜信容器云的A点与B点(分享实录)

    宜信公司从2018年初开始建设容器云,至今,容器云的常用基本功能已经趋于完善,主要包括服务管理.应用商店.Nginx配置.存储管理.CI/CD.权限管理等,支持100+业务线.3500+的容器运行.伴 ...

  10. Javascript 垃圾回收方法

    Javascript 垃圾回收方法 标记清除(mark and sweep) 这是 JavaScript 最常见的垃圾回收方式,当变量进入执行环境的时候,比如函数中声明一个变量,垃圾回收器将其标记为& ...