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 之前,我们描述了即使是很简单的赋值或更新一个字段也 ...
随机推荐
- Android Native Binder,在Native层与App交互数据
Binder底层是基于C实现的,因此可以作为Native进程与App层交互数据的渠道.其应用场景为:Native Service.Hal驱动设置.应用层JNI服务等. Android 4.4引入SEA ...
- MongoDB 谨防索引seek的效率问题【华为云技术分享】
目录 背景 初步分析 索引seeks的原因 优化思路 小结 声明:本文同步发表于 MongoDB 中文社区,传送门:http://www.mongoing.com/archives/27310 背景 ...
- 第四章 JavaScript对象及初始面向对象
创建对象: //方式一 var ower=new Object(); ower.name="长春花"; ower.genera="夹竹挑科 长春花属"; owe ...
- HDU-6113
度度熊是一个喜欢计算机的孩子,在计算机的世界中,所有事物实际上都只由0和1组成. 现在给你一个n*m的图像,你需要分辨他究竟是0,还是1,或者两者均不是. 图像0的定义:存在1字符且1字符只能是由一个 ...
- ARTS-S CentOS 7 minimal 版本安装后网络配置
用root登录服务器,执行 nmcli d 可以看到ethernet disconnected,网卡是处于禁用状态.执行 nmtui 选Edit a connection-Edit,选中Automat ...
- 【JS】379- 教你玩转数组 reduce
reduce 是数组迭代器(https://jrsinclair.com/articles/2017/javascript-without-loops/)里的瑞士军刀.它强大到您可以使用它去构建大多数 ...
- Spring Boot (二) 整合 Redis
前言 本文将会基于 springboot 2.1.8.RELEASE 简单整合 Redis ,适合新手小白入门 Spring Boot 整合 Redis 入门 1.pom.xml 中引入 redis ...
- 理解Vue中的nextTick
参考博客:https://www.jianshu.com/p/a7550c0e164f
- 4种MySQL分页查询优化的方法,你知道几个?
前言 当需要从数据库查询的表有上万条记录的时候,一次性查询所有结果会变得很慢,特别是随着数据量的增加特别明显,这时需要使用分页查询.对于数据库分页查询,也有很多种方法和优化的点.下面简单说一下我知道的 ...
- 如何上传项目到github
喜欢的同学可以看一下原文,讲得更加详细哦 原文地址:http://www.cnblogs.com/cxk1995/p/5800196.html 首先你需要一个github账号,所有还没有的话先去注册吧 ...