Aspectj 实现Method条件运行
最近我花了半个小时实现了一个Method的按自定义条件运行的plugin,Condition-Run。实现场景是由于我所工作的客户经常会是在同一个代码集上实现多个Brand,所以有些功能只会限制是几个brand调用,而其他的调用则不该调用。还有因为持续交互,我们会不停的release新的功能得到快速的反馈,在这前提下我们会经常遇见在我们刚开发完一个brand的产品代码,就要面临release,所以我们希望其不该对其他的brand产生影响。
面对这样的需求初级程序员有些人肯定会觉得没什么了不起的啊,不就是几个if/else或者switch/case。我和我的团队对代码有一种天生的洁癖,对于太多复杂的if/else和switch/case,以及将来会被移除的临时非产品代码分布在各处,有一种抵触心理。
对于有一定工作经验的程序员来说这样的需求肯定也不是什么问题,不就是AOP(面向切面编程),对,这就是我们所期望的解决方案,把处理的逻辑集中,和产品代码的分离。
知道了用AOP,也许你只对了一半,在AOP的世界里,有两种实现方式静态植入和动态代理,最早了AOP实现采用的是静态植入,然后由于IOC之类的框架的兴起,动态代理的实现方式也逐渐兴起,取代了静态植入的方式。但并不是说静态植入的方式就不再有用武之地的,在这里我们所采用的AOP框架Aspectj就是一个静态注入的框架,我们并没有和spring结合,动态代理的方式有个基本的问题就是你不能直接new这个对象这需要交给框架处理,如果是spring框架的话,这要求你必须是一个spring的bean,以及动态代理会有一些性能的损失。这对于该场景的限制太多,并不是我所期望的。
静态植入的框架在我以前的博客中也提到不少,如果感兴趣请移步 《IOC/AOP随笔目录》。在java世界里Aspectj,.net世界里PostSharp(博客中静态植入原理分析篇《MSBuild + MSILInect实现编译时AOP之预览》)就是这类框架。
回到主题,对于 condition-run如何使用请移步github文档。
这里简述如何实现:
1 对于AOP第一步是匹配规则,所以定义一个标记:
@Retention(RUNTIME)
@Target({METHOD})
public @interface ConditionRun {
Class<? extends Runner> value();
}
其指向一个实现Runner接口的类型。
2:有了匹配规则,我们就可以找到切入点进行AOP逻辑的处理,
@Aspect
public class ConditionRunAspect {
@Around("methodsToBeConditionRun(conditionRun)")
public Object profile(ProceedingJoinPoint pjp, ConditionRun conditionRun) throws Throwable {
final Result result = isExec(pjp, conditionRun);
if (result.isExec()) {
return pjp.proceed();
}
return result.getDefaultValue();
}
private Result isExec(ProceedingJoinPoint pjp, ConditionRun conditionRun) {
try {
final Runner runner = conditionRun.value().newInstance();
final MethodSignature signature = (MethodSignature) pjp.getSignature();
return runner.exec(signature, pjp.getArgs());
} catch (Exception e) {
throw new RuntimeException("Runner must be empty constructor and make sure the config is ok.", e);
}
}
@Pointcut(value = "@annotation(conditionRun)")
public void methodsToBeConditionRun(ConditionRun conditionRun) {
}
}
这里在切入方法调用之前,new了一个配置的Runner类型(注意必须午餐构造),并调用其exec方法获取是否运行该方法,如果不运行则返回什么默认值。
Runner runner = conditionRun.value().newInstance(); final MethodSignature signature = (MethodSignature) pjp.getSignature(); return runner.exec(signature, pjp.getArgs());
exec的参数签名为方法签名信息和方法运行时参数。
一切都这么简单,现在你可以任意的框架Runner去做适合你的场景业务了。可以参照项目下得sample实例,该实例展示了一个当出入参数为3的时候执行,部位3则返回默认值1.
想想还有那些场景,你是否遇见过某类单元测试我只希望运行在某种固定的场景下?假设在开发图形应用的时候,我们希望调用一些不同平台的特定api,虽然我们代码设计封装做得很好,但是我们希望有固定的集成测试去cover这部分逻辑,让我们的测试只运行是固定平台。
Aspectj 实现Method条件运行的更多相关文章
- Makefile 中:= ?= += =的差别 和条件运行
一:在Makefile中常常看到obj-m := scull.o和KERNELDIR ?= /lib/modules/等不同的赋值方式,如今总结他们的差别: = 是最主要的赋值 := 是覆盖之前 ...
- Spring Boot 2 实践记录之 条件装配
实验项目是想要使用多种数据库访问方式,比如 JPA 和 MyBatis. 项目的 Service 层业务逻辑相同,只是具体实现代码不同,自然是一组接口,两组实现类的架构比较合理. 不过这种模式却有一个 ...
- pytest文档2-用例运行规则
用例设计原则 文件名以test_*.py文件和*_test.py 以test_开头的函数 以Test开头的类 以test_开头的方法 所有的包pakege必须要有__init__.py文件 help帮 ...
- pytest_02-用例运行规则
用例设计原则 文件名以test_*.py文件和*_test.py 以test_开头的函数 以Test开头的类 以test_开头的方法 所有的包pakege必须要有__init__.py文件 help帮 ...
- 《带你装B,带你飞》pytest成神之路2- 执行用例规则和pycharm运行的三种姿态
1. 简介 今天北京下的雪好大好美啊!!!哎呀,忘记拍照片了,自己想象一下吧.言归真传,今天还是开始pytest的学习和修炼,上一篇写完后群里反响各式各样的,几家欢乐几家愁,有的高兴说自己刚好要用到了 ...
- Aspectj是什么
转载自:http://www.cnblogs.com/sunwke/articles/2568875.html 网上出现了很多讲解 AspectJ 的资料,但大多是从讲解 AspectJ 语法开始,然 ...
- Beginning Python From Novice to Professional (5) - 条件与循环
条件与循环 条件运行: name = raw_input('What is your name? ') if name.endswith('Gumby'): print 'Hello, Mr.Gumb ...
- Java AOP - Aspectj
1. 序 Aspect Oriented Programming (AOP)是近来一个比较热门的话题. AspectJ是AOP的Java语言的实现,获得了Java程序员的广泛关注. 关于AspectJ ...
- Spark Streaming + Flume整合官网文档阅读及运行示例
1,基于Flume的Push模式(Flume-style Push-based Approach) Flume被用于在Flume agents之间推送数据.在这种方式下,Spark Stre ...
随机推荐
- css总集
1 font-style normal 正常显示 italic 斜体 百分比 字体大小 font-size 像素 字体大小 font-family 字体名称 设置字体名称 letter-spacing ...
- ue4 UE4Editor.lib找不到
PublicDependencyModuleNames里加了Launch后,会导致链接UE4Editor.lib, 但这个文件在预编版的引擎里是没有的(奇怪的是自己编译引擎的话会有) 如果只是要头文件 ...
- C# 并行编程 之 轻量级手动重置事件的使用
目录(?)[-] 简单介绍 使用超时和取消 跨进程或AppDomain的同步 简单介绍 如果预计操作的等待的时间非常短,可以考虑使用轻量级的手动重置事件,ManualResetEventSlim. ...
- SQL server清空数据库日志脚本
/*设置为简单模式*/ USE [master] } SET RECOVERY SIMPLE WITH NO_WAIT } SET RECOVERY SIMPLE /*获取日志文件名称*/ } ) / ...
- 1075 PAT Judge (25)
排序题 #include <stdio.h> #include <string.h> #include <iostream> #include <algori ...
- css3的transition过渡
从*开始样式*,经过指定*时间*后,缓慢过渡到*结束样式* 语法:transition:要变化的属性名 持续时间 速度变化类型 延迟 强调:写在开始样式中 如何实现多个属性同时过渡:2种办法: 1. ...
- 安安视频网anan.video为您提供免费高清视频
安安视频网anan.video为您提供免费高清视频,最新电影,电视剧,动漫,微电影,纪录片,音乐MV在线观看(高清):安安视频网,一个干净的视频在线播放网站,百万高清影视,视频在线观看. 安安视频网整 ...
- mac系统 下 npm 安装 bower报错
在mac终端运行 sudo npm install -g bower (安装之前你要确定你已经成功安装了node 和 git) 然后会报错 like this: npm ERR! Darwin 15. ...
- 使用Wireshark 查看查找未被过滤端口
打开Wireshark ,过滤输入“ip.src == [IP] && ip.ttl < 255”,因为防火墙伪造的数据包的TTL都是255,真实的数据包应该是56,所以这句话直 ...
- "巴卡斯杯" 中国大学生程序设计竞赛 - 女生专场
Combine String #include<cstdio> #include<cstring> #include<iostream> #include<a ...