上一篇 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. 【BZOJ4001】【Luogu P3978】 [TJOI2015]概率论

    题目描述: Description: Input 输入一个正整数N,代表有根树的结点数 Output 输出这棵树期望的叶子节点数.要求误差小于1e-9 Sample Input 1 Sample Ou ...

  2. 第五章 Unity中的基础光照(3)

    目录 1. 在Unity Shader中实现高光反射光照模型 1.1 实践:逐顶点光照 1.2 逐像素光照 1.3 Blinn-Phong光照模型 2. 召唤神龙:使用Unity内置的函数 @ 1. ...

  3. 安装破解版IntelliJ IDEA

    1.下载IntelliJ IDEA http://www.jetbrains.com/idea/download/#section=windows 选择Ultimate版本 2.注册码破解 http: ...

  4. 快速搭建 Serverless 在线图片处理应用

    作者:倚贤 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute):函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数 ...

  5. Spring Boot缓存Ehcache

    Spring Boot 整合 Ehcache   修改 pom 文件 <!-- Spring Boot 缓存支持启动器 --> <dependency> <groupId ...

  6. Spring代理模式(CGLIB动态代理模式)

    jdk动态代理和CGLIB动态代理 没什么太大的区别,CGLIB动态代理不需要接口,但是需要导入jar包. 房东出租房子的方法: package com.bjsxt.proxy2; public cl ...

  7. leaflet图斑历史时空播放(附源码下载)

    前言 leaflet 入门开发系列环境知识点了解: leaflet api文档介绍,详细介绍 leaflet 每个类的函数以及属性等等 leaflet 在线例子 leaflet 插件,leaflet ...

  8. 初步了解JVM第一篇

    大家都知道,Java中JVM的重要性,学习了JVM你对Java的运行机制.编译过程和如何对Java程序进行调优相信都会有一个很好的认知. 废话不多说,直接带大家来初步认识一下JVM. 什么是JVM? ...

  9. JavaScript 原型 prototype 使用经验

    初始化一个父类,并添加方法 1function Foo(){}2Foo.prototype.sayName = function(){3    return '初始原型';4}56var foo1 = ...

  10. 解密国内BAT等大厂前端技术体系-携程篇(长文建议收藏)

    1 引言 为了了解当前前端的发展趋势,让我们从国内各大互联网大厂开始,了解他们的最新动态和未来规划.这是解密大厂前端技术体系的第四篇,前三篇已经讲述了阿里.腾讯.百度在前端技术这几年的技术发展. 这一 ...