Gadtry-Aop, Spring Aop之外的新选择
Gadtry-Aop, Spring Aop之外的新选择
作者: harbby(github) email: yezhixinghai@gmail.com 日期: 2018.12
简介
Gadtry 是一个构建于java8之上的工具库, 涵盖了Ioc
Aop
exec
graph
等等工具库,几乎涵盖了日常开发中非常多工具类,当然它还在不断丰富中.
Aop
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。(来自百度百科)
Spring-Aop和Ioc组合可以说非常漂亮和完美, Spring-Aop中定义了非常好注解和概念,可以说是对Aop模式完美诠释,Spring体系本身也非常全面, 但是Spring体系过于庞大
, 且现实中我们有太多的非Spring项目.
Gadtry-Aop
Gadtry-Aop是 Gadtry 1.1版本开始加入全新功能,旨在降低Aop使用难度,同时尽量小巧简单, 提供在Spring-Aop之外的新选择.在依赖上除了字节码操作器javassist
外无任何依赖.
Gadtry-Aop 诞生有两个目的:
其一是非spring项目 也能尽量获得Spring-Aop相似Aop体验
其二: 我非常讨厌Spring-Aop 的expression 字符串表达式和一堆的注解.它难以记忆和阅读, Gadtry-Aop 为了简化使用采用了链式(函数式)Api设计,你只需参照下demo,然后借助ide就能预览和使用所有功能,一切都是点点点
下载:
maven:
<dependency> <groupId>com.github.harbby</groupId> <artifactId>gadtry</artifactId> <version>1.1.0</version> </dependency>
非容器场景代理
这种场景非常多,就是你的项目中没有使用任何Ioc容器.
举个栗子:
T proxy = AopFactory.proxy(Class<T>) .byInstance(instance) .around(proxyContext -> { String name = proxyContext.getInfo().getName(); System.out.println(name); Object value = proxyContext.proceed(); switch (name) { case "add": Assert.assertEquals(true, value); //Set or List break; case "size": Assert.assertTrue(value instanceof Integer); break; } });
这个例子中 Class<T>
指类或接口, instance这个具体的实现类活子类实现类.这个例子中用到了 环绕通知(around)
模式. 这里注意如果Class<T>
是接口,则默认使用jdk动态代理, 否则使用字节码技术生成动态代理类.
我们在来看个结合Gadtry-Ioc容器例子
IocFactory iocFactory = GadTry.create(binder -> { binder.bind(Map.class).byCreator(HashMap::new).withSingle(); binder.bind(HashSet.class).by(HashSet.class).withSingle(); }).aop(binder -> { binder.bind("point1") .withPackage("com.github.harbby") //.subclassOf(Map.class) .classAnnotated() .classes(HashMap.class, HashSet.class) .whereMethod(methodInfo -> methodInfo.getName().startsWith("add")) .build() .before((info) -> { Assert.assertEquals("add", info.getName()); System.out.println("before1"); }) .after(() -> { Assert.assertTrue(true); System.out.println("after2"); }); }).initialize(); Set set = iocFactory.getInstance(HashSet.class);
这个例子中结合了Ioc容器来使用Aop, 在Spring开发中基本都是结合Ioc容器来使用的Aop的.
这个例子中我们 使用了扫包,过滤器等来定位需要被代理类和方法, 最后添加了 前置通知(before)
和后置通知(after)
基本概念
这篇文章中我们不会着重介绍IOC, 我们来重点看看Aop的几个概念:
-
Gadtry-Aop支持通知类型
- 前置通知(Before) 指: 在目标方法被调用之前调用通知功能。
- 后置通知(After)指: 在目标方法完成之后调用通知,无论方法正确执行与否。
- 返回通知 (after-Returning) 指: 在目标方法成功执行之后调用通知。
- 异常通知(After-throwing):在目标方法抛出异常后调用通知。
- 环绕通知(Around):通知包裹了被通知的方法,由使用者决定和调用目标方法
* 关于通知类型须知:
()->{} ,切入逻辑中无法获取目标方法相关信息,如args[]名称等 (info)->{info.getArgs()} , 这样就可以获取目标方法相关信息
- 切点(pointcut)
组成切面的最小单位, 我们通常使用明确的类和方法名称,或是利用扫描和过滤所匹配的类和方法名称来指定切点.
切点定义:
binder.bind("point1") .withPackage("com.github.harbby") //.subclassOf(Map.class) .classAnnotated() .classes(HashMap.class, HashSet.class) .whereMethod(methodInfo -> methodInfo.getName().startsWith("add")) .build() .before((info) -> { Assert.assertEquals("add", info.getName()); System.out.println("before1"); }) .after(() -> { Assert.assertTrue(true); System.out.println("after2"); });
- 切面(pointcut)
切面用来组织一组相关的切点.一个切面中可以定义多个切点
public class DemoAspect implements Aspect { @Override public void register(Binder binder) { binder.bind("point1") .classes(HashSet.class).build() .after(() -> { System.out.println("after"); }); binder.bind("point2") .classes(Map.class).build() .after(() -> { System.out.println("after"); }); } }
- 动态代理
Gadtry-Aop 优先使用jdk动态代理,如果遇到非接口无法代理时则使用Javassist动态字节码技术来代理
过滤器
在Aop中,我们通常需要指出哪些些类中的哪些些方法需要被代理拦截,Spring-Aop通过中通过expression表达式描述具体被代理的类和方法. 在Gadtry-Aop中我们细化成 类过滤
和方法过滤
,并使用简易函数式Api来表达.
-
扫描型-类过滤
withPackage(String packageName): 包过滤, 匹配此包下的所有类
subclassOf(Class<?>... subclasses): 匹配此类的子类型(包括本身类型)
classAnnotated(Class<? extends Annotation>... classAnnotations): 带有此注解的类
whereClass((classInfo)-> classInfo.getName().endsWith("impl")): 更灵活的class过滤,如按名称过滤
- 明确型-类过滤
注意和上面扫描可同时生效 为 or 的关系
推荐使用此方式. 大部分场景下需要被代理的类或接口都是可以确定下来的,使用扫描往往带来潜在未知风险
-
方法过滤
在通过上面两种方式找出需要被代理的类后, 后需要在最后进行代理方法过滤.
returnType(Class<?>... returnTypes): 匹配返回值是此类的子类型(包括本身类型)的方法
methodAnnotated(Class<? extends Annotation>... methodAnnotations):带有此注解的方法
最后
Spring-Aop太权威了,您可能无权对它做出任何改变,但是Gadtry-Aop才刚诞生不久, 如果您对Aop有什么自己的见解和想法欢迎一起来讨论和完善, 我们的地址是: https://github.com/harbby/gadtry 欢迎您的访问,里面还有更多精彩!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
java B2B2C源码电子商务平台 -----客户端负载均衡策略
一、负载均衡介绍负载均衡(Load Balance):建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。愿意了解源码的朋友直接求求交流分享技术:二一四七七七五六三三 1、服务端负载均衡:客户端请求到负载均衡服务器,负载均衡服务器根据自身的算法将该请求转给某台真正提供业务的服务器,该服务器将响应数据给负载均衡服务器,负载均衡服务器最后将数据返回给客服端。(nginx) 2、客服端负载均衡:基于客户端的负载均衡,简单的说就是在客户端程序里面,自己设定一个调度算法,在向服务器发起请求的时候,先执行调度算法计算出向哪台服务器发起请求,然后再发起请求给服务器。 二、负载均衡策略介绍(1) AbstractLoadBalancerRuleAbstractLoadBalancerRule是一个抽象类,里边主要定义了一个ILoadBalancer,定义它的目的主要是辅助负责均衡...
- 下一篇
自动化瓦力多渠道打包python脚本
自动化瓦力多渠道打包python脚本 目录介绍 1.本库优势亮点 2.使用介绍 3.注意要点 4.效果展示 5.其他介绍 0.首先看看我录制的案例演示 如下所示,这段python代码很简单,工具十分强大,一键多渠道打包工具。 项目的开源地址:https://github.com/yangchong211/YCWalleHelper 1.本库优势亮点 通过该自动化脚本,自需要run一下或者命令行运行脚本即可实现美团瓦力多渠道打包,打包速度很快 配置信息十分简单,代码中已经注释十分详细。Keystore信息一定要配置,至于渠道apk输出路径,文件配置路径等均有默认路径,没有配置也没关系 针对输出路径是根目录下的output文件夹,文件不存在则创建,文件存在则是先删除之前多渠道打包生成的【也就是删除output文件夹下所有文件】,然后在重新生成 多渠道的定义是在channel这个文件中,建议是txt文件格式,你可以根据项目情况修改,十分快捷 如果瓦力打包工具更新了,直接替换一下lib中的jar即可。可以在python3.x上跑起来! 我也参考了大量的博客,网上博客很多,我始终觉得对于这种实操...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Mario游戏-低调大师作品
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS关闭SELinux安全模块