上一篇 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. (python)查看糗事百科文字 点赞 作者 等级 评论

    import requestsimport reheaders = { 'User-Agent':'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; ...

  2. LeetCode-7.reverse-integer 【翻转字符串】【数学】

    PS: 第一次写文章好累啊,没想到这么短的文章写完这么累,大家给我点反馈,多给我留言啊.

  3. js3——表格下拉

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  4. ASP.NET Core 选项模式源码学习Options Configure(一)

    前言 ASP.NET Core 后我们的配置变得更加轻量级了,在ASP.NET Core中,配置模型得到了显著的扩展和增强,应用程序配置可以存储在多环境变量配置中,appsettings.json用户 ...

  5. SQL语句中将形式(12/10/19 4:13:21 PM)转化为(2019-12-10)

    convert(char(10),convert(datetime, H.TOEX_FIN_REJECT_TIMR)+1,20),

  6. Dubbo初步

    Dubbo 介绍 : Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的RPC 实现服务的输出和输入功能,可以和 Spring 框架无缝集成.Dubbo 框架,是基于容器 ...

  7. ASE19团队项目beta阶段Backend组 scrum6 记录

    本次会议于12月12日,19:30在微软北京西二号楼sky garden召开,持续10分钟. 与会人员:Zhikai Chen, Lihao Ran, Xin Kang 请假人员:Hao Wang 每 ...

  8. HDU-6115

    我们将A省简化为由N个城市组成,某些城市之间存在双向道路,而且A省的交通有一个特点就是任意两个城市之间都能通过道路相互到达,且在不重复经过城市的情况下任意两个城市之间的到达方案都是唯一的.聪明的你一定 ...

  9. ARTS-S python把非汉语和非字母的字符替换成空格

    # coding: utf-8 import re text = "aa[bb,aa#cWc中a国" FILTER_PUNTS = re.compile("[^\u4E0 ...

  10. 蛋疼的 qii 神马警告才是需要注意的警告?(由于警告引起的截然不同的运行结果)解决总结

    接上文!! 蛋疼一天,折腾一天,没找到具体原因,但是找到了具体操作办法! 1.果断删除没用的文件 特别是sdc文件,旧的没用,果断删除,否则系统会默认使用,带来副作用 2.files 添加系统用到的i ...