有一个这样的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Question {}
被注解的文件如下
@Question
public class SomeQuestion {
public void foo(){}
}
现在的问题是,我想在 annotation processor 中,拿到被注解文件的源代码,这里就是
public class SomeQuestion {
public void foo(){}
}
如何做到呢?求助!
添加一个stackoverflow上的回答吧。以下
Java's standard annotation processors provide a callback only at declarations, such as method and field declarations.
It's possible to use an annotation processor to analyze expressions, but it's a bit more work. You will have to write an annotation processor that, at each method, obtains the AST (abstract syntax tree or parse tree) for the method and then visits each expression in the method. The AST is compiler-specific.
The two best-known projects that do this are the Checker Framework and Project Lombok. Maybe you could take inspiration from their implementations, or even write your annotation processor on top of one of them.
大概意思是,java annotation processer 只能拿到声明级别的信息,如类,方法的声明相关信息,拿不到其定义的内容。要想拿到类和方法定义的具体内容,需要使用到AST。
鉴于我的需要只是拿到源文件的内容,我还是使用读取文件的方式好了。。。
1
freebird1994 2020-06-01 22:05:32 +08:00 via Android
将类注入到 spring 容器中。实现 beanPostProcessor 。可以对注入容器的 bean 进行操作
|
2
freebird1994 2020-06-01 22:09:16 +08:00 via Android
@freebird1994 我好像理解错了楼主的意思?拿源代码?这个怕是只能通过类似 asm 等去获取字节码吧?还能拿到源代码么…看下楼下有没有大佬指点一下
|
3
luckylo 2020-06-01 22:12:05 +08:00 via Android
个人觉得不可能。注解只在源代码中生效,编译后被擦除了。根本不能拿到任何东西
|
4
fantastM 2020-06-01 22:53:47 +08:00
楼主说的 annotation processor 应该是 https://docs.oracle.com/javase/8/docs/api/javax/annotation/processing/AbstractProcessor.html
这是作用在 javac 阶段的,类似于 Lombok 的注解 |
5
Jrue0011 2020-06-01 22:56:12 +08:00
额。。反正是源码级别,获取到类名后根据是外部类、内部类在整个项目目录下找对应的源码文件读取?
|
6
inwar 2020-06-01 22:59:21 +08:00 via Android
想到个思路,打包的时候把源码复制一份到 resource, 注解改成 runtime,获取带包名的类名, 根据长类名读取 resouece 目录下源码文件。
有点黑魔法,不知道楼下有没有好的方案 |
8
Jirajine 2020-06-01 23:02:36 +08:00 via Android
annotation 类似卫生宏吧,这种需求应该没问题才对。
|
9
asanelder OP |
11
Jirajine 2020-06-01 23:40:47 +08:00 via Android
@asanelder 又看了一下,我弄错了,annotation 只能存元数据,你可以把类当参数传给你的 annotation 。
如果需要注入代码的话可以通过反射,参考这个 https://stackoverflow.com/questions/1079343/java-simple-technique-for-annotation-based-code-injection |
12
zengmingyang96 2020-06-02 00:06:51 +08:00
用构建工具来做这件事情或许更好
|
13
asanelder OP @zengmingyang96 #12 嗯,应该是另一种思路,只是最近突然想起 annotation,正好有一个小需求,就练习一下下
|
14
wangyanrui 2020-06-02 08:43:43 +08:00
抄一下 Lombok 应该可以的吧
|
15
guyeu 2020-06-02 10:18:04 +08:00
原始需求是啥呢。。如果你发现一种实现很别扭,或许可以重新考虑下需求。
|
16
gaius 2020-06-02 13:01:59 +08:00 via Android
读源码不得读 java 文件吗,要么反编译 class 。。不知道你想干什么,如果是增强类可以用 cglib 之类的
|
17
strawberryBug 2020-06-02 13:40:48 +08:00
注解都是要设定 @Target 的,仅能拿到 Target 支持的类型(枚举类)
|
18
asanelder OP |