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

栏目: 编程工具 · 发布时间: 5年前

内容简介:作者: harbby(github) email:​ Gadtry 是一个构建于java8之上的工具库, 涵盖了​ 在软件业,AOP为Aspect Oriented Programming的缩写,意为:

Spring Aop之外的新选择Gadtry-Aop

作者: harbby(github) email: yezhixinghai@gmail.com 日期: 2018.12

简介

​ Gadtry 是一个构建于 java 8之上的 工具 库, 涵盖了 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 欢迎您的访问,里面还有更多精彩!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

个性化网页设计与鉴赏

个性化网页设计与鉴赏

梁景红 / 西安电子科技大学出版社 / 2003-07-14 / 22.00

本书比较全面地介绍了网页设计应注意的相关问题, 在网页设计基础方面着重讲解了网页框架、页面元素、色彩设计,分析了一些人们容易忽视的细小环节,如页面装饰物、图片、文字、连接等。书中结合实例分析了优秀网页的设计创意思想,可以给读者提供一些启示。书中还介绍了作为网页设计者需要了解的信息管理和技术应用,以及网站VI设计和视觉美学等必要知识,读者可针对各种类别的站点具体实践这些知识,寻找进行网页设计的切入点......一起来看看 《个性化网页设计与鉴赏》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试