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 之前,我们描述了即使是很简单的赋值或更新一个字段也 ...
随机推荐
- 【10分钟学Spring】:@Profile、@Conditional实现条件化装配
根据不同的环境来装配不同的bean 企业级开发中,我们一般有多种环境,比如开发环境.测试环境.UAT环境和生产环境.而系统中有些配置是和环境强相关的,比如数据库相关的配置,与其他外部系统的集成等. 如 ...
- html元素是否包含另外一个元素,以及classList属性
如何判断一个元素A包含了元素B呢?如果不用contains方法的话,如何做呢? 腾讯面试的时候也出了这道题啊,当时没看dom的知识,所以一抹黑哦... 那就判断B是否为A的child喽,那也就是A是B ...
- webpack-优化阻塞的css
随着浏览器的日新月异,网页的性能和速度越来越好,并且对于用户体验来说也越来越重要. 现在有很多优化页面的办法,比如:静态资源的合并和压缩,code splitting,DNS预读取等等. 本文介绍的是 ...
- 这个七夕节,用Python为女友绘制一张爱心照片墙吧!【华为云技术分享】
欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),输入关键字“加群”,加入华为云线上技术讨论群:输入关键字“最新活动”,获取华为云最新特惠促销.华为云诸多技术大咖.特 ...
- 搞清楚一道关于Integer的面试题
请看题1: public class IntegerDemo { public static void main(String[] args) { Integer a = 888; Integer b ...
- luogu P1731 [NOI1999]生日蛋糕 |暴力枚举
题目背景 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层 生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1<=i<=M)层蛋糕是半径为Ri, 高度为Hi的圆柱 ...
- multipart/form-data 文件上传表单中 传递参数无法获取的原因!
1.什么是multipart/form-data 首先我们需要明白在html中的enctype属性, enctype:规定了form表单在发送到服务器时候编码方式.他有如下的三个值. ①applica ...
- Java修炼——继承_super父类对象的引用
Super是指直接父类对象的引用,可以通过super来访问父类中被子类覆盖的方法和属性. 当你调用子类的构造方法时,系统会默认给你先调用父类的构造方法,然后才会调用子类的构造方法. package c ...
- B.Beautiful Numbers
题意:你被给予了一个序列 p = [p1, p2, ..., pn](1 ~ n的整数),如果存在l, r左右端点(1 <= l <= r <= n),使得[pl, pl+1,... ...
- Java并发:线程限制
最近又学到了很多新知识,感谢优锐课老师细致地讲解,这篇博客记录下自己所学所想,也和大家分享.了解有关Java中的并发问题和线程限制的更多信息. 在此文中,我们将探讨线程限制,它的含义以及如何实现.因此 ...