文档章节

Gadtry-Aop, Spring Aop之外的新选择

ideal_github_harbby
 ideal_github_harbby
发布于 12/06 12:01
字数 1634
阅读 154
收藏 3

Spring Aop之外的新选择Gadtry-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的几个概念:

    1. 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 的关系

    推荐使用此方式. 大部分场景下需要被代理的类或接口都是可以确定下来的,使用扫描往往带来潜在未知风险

    • classes(HashMap.class, HashSet.class): 如明确只代理HashMap和HashSet两个类(不涵子类)实例
      
  • 方法过滤

    在通过上面两种方式找出需要被代理的类后, 后需要在最后进行代理方法过滤.

    • returnType(Class<?>... returnTypes): 匹配返回值是此类的子类型(包括本身类型)的方法
      
    • methodAnnotated(Class<? extends Annotation>... methodAnnotations):带有此注解的方法
      
    • whereMethod(methodInfo -> methodInfo.getName().startsWith("add")): 更加灵活的方法过滤,如:此处匹配出名称为add开头的方法
      

最后

​ Spring-Aop太权威了,您可能无权对它做出任何改变,但是Gadtry-Aop才刚诞生不久, 如果您对Aop有什么自己的见解和想法欢迎一起来讨论和完善, 我们的地址是: https://gitee.com/mirrors/Gadtry 欢迎您的访问,里面还有更多精彩!

© 著作权归作者所有

共有 人打赏支持
ideal_github_harbby
粉丝 3
博文 5
码字总数 7006
作品 2
成都
私信 提问
加载中

评论(7)

ideal_github_harbby
ideal_github_harbby

引用来自“红薯”的评论

代码托管在码云吧,我们推荐一下:)

引用来自“ideal_github_harbby”的评论

红薯老板 早上好😊, 软件已经被收录了 https://www.oschina.net/p/gadtry

引用来自“红薯”的评论

是说托管到 gitee.com 一份啦 :)

引用来自“ideal_github_harbby”的评论

这个算吗? https://gitee.com/mirrors/Gadtry 还是我继续在自己账号下面托管一份

引用来自“红薯”的评论

这个不算,弄到你自己账号下吧 :)

引用来自“ideal_github_harbby”的评论

ok 好的
已经可以了😄 https://gitee.com/idela-hp/gadtry
ideal_github_harbby
ideal_github_harbby

引用来自“红薯”的评论

代码托管在码云吧,我们推荐一下:)

引用来自“ideal_github_harbby”的评论

红薯老板 早上好😊, 软件已经被收录了 https://www.oschina.net/p/gadtry

引用来自“红薯”的评论

是说托管到 gitee.com 一份啦 :)

引用来自“ideal_github_harbby”的评论

这个算吗? https://gitee.com/mirrors/Gadtry 还是我继续在自己账号下面托管一份

引用来自“红薯”的评论

这个不算,弄到你自己账号下吧 :)
ok 好的
红薯
红薯

引用来自“红薯”的评论

代码托管在码云吧,我们推荐一下:)

引用来自“ideal_github_harbby”的评论

红薯老板 早上好😊, 软件已经被收录了 https://www.oschina.net/p/gadtry

引用来自“红薯”的评论

是说托管到 gitee.com 一份啦 :)

引用来自“ideal_github_harbby”的评论

这个算吗? https://gitee.com/mirrors/Gadtry 还是我继续在自己账号下面托管一份
这个不算,弄到你自己账号下吧 :)
ideal_github_harbby
ideal_github_harbby

引用来自“红薯”的评论

代码托管在码云吧,我们推荐一下:)

引用来自“ideal_github_harbby”的评论

红薯老板 早上好😊, 软件已经被收录了 https://www.oschina.net/p/gadtry

引用来自“红薯”的评论

是说托管到 gitee.com 一份啦 :)
这个算吗? https://gitee.com/mirrors/Gadtry 还是我继续在自己账号下面托管一份
红薯
红薯

引用来自“红薯”的评论

代码托管在码云吧,我们推荐一下:)

引用来自“ideal_github_harbby”的评论

红薯老板 早上好😊, 软件已经被收录了 https://www.oschina.net/p/gadtry
是说托管到 gitee.com 一份啦 :)
ideal_github_harbby
ideal_github_harbby

引用来自“红薯”的评论

代码托管在码云吧,我们推荐一下:)
红薯老板 早上好😊, 软件已经被收录了 https://www.oschina.net/p/gadtry
红薯
红薯
代码托管在码云吧,我们推荐一下:)
Gratry-1.1.0 发布, Spring Aop 之外的新选择

简介: Gadtry 是一个构建于java8之上的工具库, 涵盖了 等等工具库,几乎涵盖了日常开发中非常多工具类,当然它还在不断丰富中. Gadtry 1.1.0 稳定版已发布,主要新增Aop功能,特点如下: 新增完...

ideal_github_harbby
12/06
0
0
2014-03-11 Spring的学习(3)------面向切面编程(AOP)

AOP概念 首先让我们从一些重要的AOP概念和术语开始。这些术语不是Spring特有的。不过AOP术语并不是特别的直观,如果Spring使用自己的术语,将会变得更加令人困惑。 切面(Aspect):一个关注...

查封炉台
2014/03/11
0
0
ideal(github-harbby)/gadtry

Gadtry Gadtry A collection of java tool libraries. Contains: ioc. aop. exec. graph ... Use maven com.github.harbbygadtry1.1.0 Ioc Create Factory: IocFactory iocFa......

ideal(github-harbby)
12/07
0
0
《Spring5学习》04 - 面向切面编程

一、Spring面向切面编程的基本概念 面向切面编程(即AOP):把项目中需要再多处使用的功能比如日志、安全和事务等集中到一个类中处理,而不用在每个需要用到该功能的地方显式调用。 横切关注...

老韭菜
08/19
0
0
Aspectj与Spring AOP比较

1、简介 今天有多个可用的 AOP 库, 它们需要能够回答许多问题: 是否与用户现有的或新的应用程序兼容? 在哪里可以实现 AOP? 与自己的应用程序集成多快? 性能开销是多少? 在本文中, 我们将...

沈渊
04/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Netty handle方法周期 (四)

写了一个练习之后,发现自定义的助手类每次肯定是必须的,对于不同的业务逻辑需求,会写相对应的逻辑 最简单的查看Handle生命周期的方式,就是重写上级方法,看名字差不多应该可以知道方法的作用 ...

_大侠__
13分钟前
2
0
vue主动刷新页面及列表数据删除后的刷新实例

1.场景 在处理列表时,常常有删除一条数据或者新增数据之后需要重新刷新当前页面的需求。 2.遇到的问题 1. 用vue-router重新路由到当前页面,页面是不进行刷新的 2.采用window.reload(),或者...

前端小攻略
23分钟前
5
0
闲话高并发的那些神话,看京东架构师如何把它拉下神坛

高并发也算是这几年的热门词汇了,尤其在互联网圈,开口不聊个高并发问题,都不好意思出门。高并发有那么邪乎吗?动不动就千万并发、亿级流量,听上去的确挺吓人。但仔细想想,这么大的并发与...

James-
29分钟前
4
0
Emacs 系列:让我们拥抱 Emacs 和 org 模式

导读 我必须承认,在使用了几十年的 vim 后, 我被 Emacs 吸引了。长期以来,我一直对如何组织安排事情感到沮丧。我也有用过 GTD 和 ZTD 之类的方法,但是像邮件或是大型文件这样的事务真的很...

问题终结者
29分钟前
5
0
解析Node.js通过axios实现网络请求

本次给大家分享一篇node.js通过axios实现网络请求的方法,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下。如有不足之处,欢迎批评指正。 1、使用Npm 下载axios n...

前端攻城老湿
42分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部