最近我花了半个小时实现了一个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逻辑的处理,

@Aspectpublic 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这部分逻辑,让我们的测试只运行是固定平台。

转载于:https://www.cnblogs.com/whitewolf/p/3175902.html

Aspectj 实现Method条件运行相关推荐

  1. Makefile 中:= ?= += =的差别 和条件运行

    一:在Makefile中常常看到obj-m    := scull.o和KERNELDIR ?= /lib/modules/等不同的赋值方式,如今总结他们的差别: = 是最主要的赋值 := 是覆盖之前 ...

  2. matlab滤除某一频率的信号,设计一个matlab带通滤波器代码采样频率10Hz,滤除除0.9-1.1Hz之外的其他信号,信号输入为x1,输出为x2,不明白的问我可以追加条件,运行好使的追加分...

    优质解答 % 用切比雪夫最佳一致逼近设计线性相位FIR带通滤波器: %信号为0.5hz, 0.9hz, 1.1hz和1.5hz的正统信号叠加组成 %通带为[0.9,1.1] %频谱分辨率与信号实际长度 ...

  3. Spring Boot 2 实践记录之 条件装配

    实验项目是想要使用多种数据库访问方式,比如 JPA 和 MyBatis. 项目的 Service 层业务逻辑相同,只是具体实现代码不同,自然是一组接口,两组实现类的架构比较合理. 不过这种模式却有一个 ...

  4. 比较Spring AOP和AspectJ

    1. 介绍 当前有多个可用的AOP库,这些库必须能够回答许多问题: 它与我现有的或新的应用程序兼容吗? 在哪里可以实施AOP? 它与我的应用程序集成的速度有多快? 性能开销是多少? 在本文中,我们将着 ...

  5. python代码设计测试用例_《带你装B,带你飞》pytest成神之路2- 执行用例规则和pycharm运行的三种姿态...

    1. 简介 今天北京下的雪好大好美啊!!!哎呀,忘记拍照片了,自己想象一下吧.言归真传,今天还是开始pytest的学习和修炼,上一篇写完后群里反响各式各样的,几家欢乐几家愁,有的高兴说自己刚好要用到了 ...

  6. AspectJ 学习笔记

    学习完AspectJ有段时间了,总体感觉这个编程语言简单易学.功能强大,但是搜到的关于AspectJ的基础内容比较少,so,笔者感觉有必要整理出这部分内容,若有不当之处,欢迎指正共同学习☺ 内容:As ...

  7. JVM学习笔记之-运行时数据区概述及线程概述,程序计数器(PC寄存器),虚拟机栈(栈,局部变量表,操作数栈,动态连接,方法调用,方法返回地址等),本地方法接口,本地方法栈

    运行时数据区概述及线程概述 内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时运行.JVM内存布局规定了Java在运行过程中内存申请.分配.管理的策略,保证了JV ...

  8. Simpy学习:基本运行与终止(一)

    对应教程:https://simpy.readthedocs.io/en/latest/simpy_intro/basic_concepts.html 博主是第一次使用仿真,下面是一些学习心得与知识点 ...

  9. uiautomator-CTS上运行,出xml报告

    一.CTS 介绍与命令说明 主要介绍: CTS下载与配置 CTS目录说明 CTS基本命令说明 Windows系统下运行CTSCTS 全称Compatibility Test Suite 兼容性测试套件 ...

最新文章

  1. 数学知识--Unconstrained Optimization(第二章)
  2. 网络推广是做什么的知道网站做301定向跳转对优化有什么帮助?
  3. LESSON 12.8 原理进阶 (1):GBDT数学流程与残差概念辨析
  4. html5media.js 让浏览器兼容VideoAudio 标签
  5. vba 字典_VBA中字典的基础概念及调用方法
  6. extern 在c/c++ 中的作用
  7. 链表中环的入口结点 python_【Github 5K星】BAT头条滴滴小米等笔试面经+深度学习/算法/NLP资源汇总!...
  8. 使用wget从网上下载ubuntu源到互联网硬盘,拿到内部用
  9. 【生活】深圳驾考经历
  10. 2021SAAE上海第七届教育装备展览会
  11. Beaglebone Black 和树莓派
  12. Bulma的简单使用
  13. oracle创建列默认值,表列添加默认值的方法
  14. php 解析pathinfo 类
  15. mac电脑打不开应用程序的解决方法
  16. 搭建Web环境初识JSP
  17. 14个岗位,看完就知道自己在互联网行业该怎么混
  18. Mac实用小技巧-alfred 集成idea
  19. [转]关于做好2015年许昌市城区小学招生工作的通知
  20. Cocos2dx 小技巧(三)Label的换行

热门文章

  1. C#使用读写锁三行代码简单解决多线程并发写入文件时线程同步的问题
  2. PAT:1042. Shuffling Machine (20) AC
  3. BlendMode类
  4. linux 安装 memcached
  5. webpack4.0各个击破(2)—— CSS篇
  6. 第四章:Spring AOP
  7. Bash shell的内建命令:type
  8. 开源docker轻量级管理平台shipyard部署(中文版)
  9. jquery_选择器
  10. Excel生成报表之解决方案--设置单个单元格格式