V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ychost
V2EX  ›  Java

FastAop,一款基于 Java 编译时的 Aop 框架

  •  
  •   ychost · 41 天前 · 1684 次点击
    这是一个创建于 41 天前的主题,其中的信息可能已经有所发展或是发生改变。

    项目地址

    https://github.com/fast-light/fastaop

    项目刚上线,后面会持续维护,Maven 中央仓库还在申请中

    项目简介

    FastAop 是一款基于 Java Annotation Processing 的 AOP 框架,其原理和 Lombok 类似,通过对编译过程的拦截,修改方法的语法树并织入切面代码从而实现了 AOP 的功能,相较于传统的 AspectJ 、Spring-AOP 框架有如下特点:

    1. 依赖干净,无需 Spring 等环境
    2. 使用简单,仅需两个注解就能实现切面功能
    3. 性能好,由于是编译过程中植入原生代码,所以性能几乎无损
    4. 功能强大,支持 private 、static 等各种方法切面,内部方法相互调用也会过切面逻辑
    5. 扩展性好,提供了特定注解,能够在方法内部拿到当前切面上下文,便于做一些临时操作

    项目由来

    在写一些二方库的时候,有时候会有 aop 需求,但是又不想引入 AspectJ 或者 Spring 这种重量级的框架,那么 FastAop 就是你的另一个选择,原理和 Lombok 一样在编译的时候修改语法树注入的切面代码,目前已用在了生产环境,当然可以基于这个库可以生成任何你想要的模板代码,欢迎大家一起交流~

    27 条回复    2021-04-01 15:12:21 +08:00
    blindpirate
        1
    blindpirate   41 天前
    所以它也像 lombok 一样违反了 annotation processor 的规定,在 annotation processing 的过程中使用了 javac 的私有 API,修改了生成的文件?
    dbpe
        2
    dbpe   41 天前
    同 1L 的疑问...
    ychost
        3
    ychost   41 天前
    @blindpirate 是的,调用了 javac 的 api 去织入了切面代码,传统的 Aop 在运行时也会改 class 文件
    ychost
        4
    ychost   41 天前
    @dbpe 是的,编译的时候魔改了语法树
    dqzcwxb
        5
    dqzcwxb   41 天前
    cglib?
    ychost
        6
    ychost   41 天前
    @dqzcwxb 不是,用的 Java 自带的 Annotation Processor 技术
    bthulu
        7
    bthulu   41 天前
    最烦这种在编译过程中干黑活的, 能不用还是不要用了
    ychost
        8
    ychost   41 天前
    @bthulu 编译干活和运行时干活本质差不多,都是魔改,受限于 Java 语法限制只能通过注解处理来搞定,如果有 C#/Kotlin 那么灵活就不会出现 Lombok 这样的框架了
    JinTianYi456
        9
    JinTianYi456   41 天前
    @blindpirate 想了解下 "lombok 一样违反了 annotation processor 的规定",弱弱问下,是违反了什么规定?
    chendy
        10
    chendy   41 天前
    star 了,之前玩过代码生成,这次看看到底怎么黑 javac
    zhao1014
        11
    zhao1014   41 天前 via Android
    同不了解 annotation processor 规定是什么,有老哥大致解释一下吗?
    lewis89
        12
    lewis89   41 天前   ❤️ 1
    @bthulu 能做到透明,其实还好,看能不能支持 aspectJ 的 切点语法 以及环绕监听...
    其实.. 说白了 还是上 SpringBoot 吧.. 现在这些框架 AOP 以及各种组件 都做的非常好了,搞 Java 的根本不在乎轻量化这个东西,关键是思维负担上的轻量化,至于本身生成的代码尺寸,我觉得都不是什么大事..
    ychost
        13
    ychost   41 天前
    @lewis89 这个项目的初衷主要是为了解决两个东西,1. Aop 性能问题(实测) 2. 二方库用 Aop,二方库依赖过重会导致排包困难,版本冲突等问题
    ychost
        14
    ychost   41 天前
    @ychost 实测性能是高于 Cglib 和 JDK 动态代理,这几个性能都很高性能损失在 0.3% 左右,FastAop 性能损失在 0.1%
    blindpirate
        15
    blindpirate   41 天前
    @JinTianYi456
    @zhao1014

    Java 的 AP spec 只允许在 AP 的时候生成新文件,不允许修改已有的编译输出,i.e. compiled class 。lombok 违反了这个规定,且有传染性(一个人用就逼迫所有人都要安装插件),因此我个人不喜欢用 lombok 。

    > The "hack" in Lombok is that, strictly speaking, the annotation processing spec doesn't allow you to modify existing classes. The annotation processing API doesn't provide a mechanism for changing the AST of a class. The clever people at Project Lombok got around this through some unpublished APIs of javac.

    另,“修改编译输出的 class 文件”和“AOP 在运行时修改载入 JVM 的 Class 对象”是两个概念,前者属于 AST 变换,后者属于 bytecode manipulation
    Betsy
        16
    Betsy   41 天前 via iPhone
    没有单元测试,这看着有点慌哈。
    我试了下,windows 系统 mvn clean package 也打不出来包,会报错
    ychost
        17
    ychost   41 天前
    @Betsy 项目刚上线,还没来得及补测试用例,windows 系统的问题,我晚上装个虚拟机看看,我在 mac 下面测 JDK8 没问题的
    beichenhpy
        18
    beichenhpy   41 天前
    运行 install.sh 后,在新的 maven 项目中还是无法引入。。奇怪了,明明在本地仓库中看到了
    beichenhpy
        19
    beichenhpy   40 天前
    @ychost 编译空指针咋回事
    ychost
        20
    ychost   40 天前
    @beichenhpy 提个 issue 我看看
    cubecube
        21
    cubecube   40 天前
    有 benchmark 么?运行时,已预热的的 benchmark 。
    VHacker1989
        22
    VHacker1989   40 天前
    早就有人做过了,比如 micronaut,把 aop,ioc 都做到了编译时,还支持 graalvm native build 。
    LessonOne
        23
    LessonOne   40 天前
    @ychost 应该没人会在意 这 0.2%的差距吧???
    ychost
        24
    ychost   40 天前
    @cubecube
    @LessonOne
    性能差异可以忽略,主要目的是可以自己生成模板代码,不光是 aop,其它你想要的都能生成
    ychost
        25
    ychost   40 天前
    @VHacker1989 micronaut 这个很优秀,但是它这个是对标 Spring 这种生态级别的,目的不一样,我这个只是个小工具
    ychost
        26
    ychost   37 天前
    稍微翻了下 micronaut aop 的源码,它那个是通过继承替换 Bean 实现切面的,所以不能切内部方法、静态方法,好处是生成的一抹多文件,没有改源文件,生成的代码都是继承于源文件
    ychost
        27
    ychost   37 天前
    @LessonOne 稍微翻了下 micronaut aop 的源码,它那个是通过继承替换 Bean 实现切面的,所以不能切内部方法、静态方法,好处是生成的一抹多文件,没有改源文件,生成的代码都是继承于源文件
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1991 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 05:11 · PVG 13:11 · LAX 22:11 · JFK 01:11
    ♥ Do have faith in what you're doing.