https://github.com/fast-light/fastaop
项目刚上线,后面会持续维护,Maven 中央仓库还在申请中
FastAop 是一款基于 Java Annotation Processing 的 AOP 框架,其原理和 Lombok 类似,通过对编译过程的拦截,修改方法的语法树并织入切面代码从而实现了 AOP 的功能,相较于传统的 AspectJ 、Spring-AOP 框架有如下特点:
在写一些二方库的时候,有时候会有 aop 需求,但是又不想引入 AspectJ 或者 Spring 这种重量级的框架,那么 FastAop 就是你的另一个选择,原理和 Lombok 一样在编译的时候修改语法树注入的切面代码,目前已用在了生产环境,当然可以基于这个库可以生成任何你想要的模板代码,欢迎大家一起交流~
1
blindpirate 2021-03-29 10:23:41 +08:00
所以它也像 lombok 一样违反了 annotation processor 的规定,在 annotation processing 的过程中使用了 javac 的私有 API,修改了生成的文件?
|
2
dbpe 2021-03-29 10:27:47 +08:00
同 1L 的疑问...
|
3
ychost OP @blindpirate 是的,调用了 javac 的 api 去织入了切面代码,传统的 Aop 在运行时也会改 class 文件
|
5
dqzcwxb 2021-03-29 10:40:15 +08:00
cglib?
|
7
bthulu 2021-03-29 10:51:43 +08:00
最烦这种在编译过程中干黑活的, 能不用还是不要用了
|
8
ychost OP @bthulu 编译干活和运行时干活本质差不多,都是魔改,受限于 Java 语法限制只能通过注解处理来搞定,如果有 C#/Kotlin 那么灵活就不会出现 Lombok 这样的框架了
|
9
JinTianYi456 2021-03-29 11:05:14 +08:00
@blindpirate 想了解下 "lombok 一样违反了 annotation processor 的规定",弱弱问下,是违反了什么规定?
|
10
chendy 2021-03-29 11:09:19 +08:00
star 了,之前玩过代码生成,这次看看到底怎么黑 javac
|
11
zhao1014 2021-03-29 11:09:51 +08:00 via Android
同不了解 annotation processor 规定是什么,有老哥大致解释一下吗?
|
12
lewis89 2021-03-29 11:11:20 +08:00 1
@bthulu 能做到透明,其实还好,看能不能支持 aspectJ 的 切点语法 以及环绕监听...
其实.. 说白了 还是上 SpringBoot 吧.. 现在这些框架 AOP 以及各种组件 都做的非常好了,搞 Java 的根本不在乎轻量化这个东西,关键是思维负担上的轻量化,至于本身生成的代码尺寸,我觉得都不是什么大事.. |
13
ychost OP @lewis89 这个项目的初衷主要是为了解决两个东西,1. Aop 性能问题(实测) 2. 二方库用 Aop,二方库依赖过重会导致排包困难,版本冲突等问题
|
14
ychost OP @ychost 实测性能是高于 Cglib 和 JDK 动态代理,这几个性能都很高性能损失在 0.3% 左右,FastAop 性能损失在 0.1%
|
15
blindpirate 2021-03-29 11:40:41 +08:00
@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 |
16
Betsy 2021-03-29 12:08:31 +08:00 via iPhone
没有单元测试,这看着有点慌哈。
我试了下,windows 系统 mvn clean package 也打不出来包,会报错 |
17
ychost OP @Betsy 项目刚上线,还没来得及补测试用例,windows 系统的问题,我晚上装个虚拟机看看,我在 mac 下面测 JDK8 没问题的
|
18
uselessVisitor 2021-03-29 13:02:22 +08:00
运行 install.sh 后,在新的 maven 项目中还是无法引入。。奇怪了,明明在本地仓库中看到了
|
19
uselessVisitor 2021-03-29 13:17:20 +08:00
@ychost 编译空指针咋回事
|
20
ychost OP @beichenhpy 提个 issue 我看看
|
21
cubecube 2021-03-30 00:59:46 +08:00
有 benchmark 么?运行时,已预热的的 benchmark 。
|
22
VHacker1989 2021-03-30 07:52:47 +08:00
早就有人做过了,比如 micronaut,把 aop,ioc 都做到了编译时,还支持 graalvm native build 。
|
24
ychost OP |
25
ychost OP @VHacker1989 micronaut 这个很优秀,但是它这个是对标 Spring 这种生态级别的,目的不一样,我这个只是个小工具
|
26
ychost OP 稍微翻了下 micronaut aop 的源码,它那个是通过继承替换 Bean 实现切面的,所以不能切内部方法、静态方法,好处是生成的一抹多文件,没有改源文件,生成的代码都是继承于源文件
|
27
ychost OP @LessonOne 稍微翻了下 micronaut aop 的源码,它那个是通过继承替换 Bean 实现切面的,所以不能切内部方法、静态方法,好处是生成的一抹多文件,没有改源文件,生成的代码都是继承于源文件
|
28
dk7952638 2021-12-15 08:03:12 +08:00
我觉得可以参照 dagger 的思路通过 annotation porcessor 来实现接口,在接口里生成 aop 过程比较好一些,lombok 的方式一不是规范,二兼容性和移植性太差
|