问题描述
我知道自定义 Java 注释需要一个带有 @interface
的半接口声明和一个处理器代码(在某些文本中称为消费者代码),它定义了注释背后的实际业务逻辑。到目前为止很清楚,但我的问题是,处理器代码在何处/何时被调用,由谁调用?我的意思是,Java 编译器是否会生成调用所有注释处理器的代码,例如,在类加载时?或者程序员自己决定何时为他们的自定义注释调用他们的处理器代码?
例如,某些方法上的 @GetMapping("/users")
告诉 servlet API 将请求与 /users 映射到其请求路径中,应将其传递给此方法。所以它在幕后有一些处理器,应该被调用将这个映射配置存储在某处,但是什么时候调用那个处理器,谁调用呢?我想我的问题只对 @Retention(RetentionPolicy.RUNTIME)
的注释有意义。谢谢
解决方法
annotation processor 在编译时运行。调用 javac
时,用户传递 -processor
命令行选项,然后 javac
调用处理器。注释处理器可以发出错误、创建文件(包括 Java 代码文件),甚至修改现有代码。除了上面链接的 Oracle 文档之外,您可能还想查看教程,例如 Baeldung's。
有些框架直接解释注解,所以不需要自己编写注解处理器。为了影响运行时行为,您的代码可以反射性地读取注释;在这种情况下,在编译时没有运行注释处理器。
,顾名思义,Annotation
是附加信息(或行为)。默认情况下,此信息不会被处理或用于改变任何行为。必须有一些实体来处理注释。
保留策略告诉 Java 编译器注释的范围。即额外的信息需要在运行时还是编译时处理。
对于编译时处理,annotation processors
使用 -processor
标志挂钩到编译过程中。对于运行时处理,反射(例如 this)用于访问附加信息。
@GetMapping("/users") 在某些方法上,告诉 servlet API 将请求映射到请求路径中的 /users,
仅存在注释不会导致此行为。 spring框架(简化了很多)-
- 将自身安装为
/*
的 servlet 端点。见FrameworkServlet - 使用反射枚举用
GetMapping
注释的方法 - 使用带注释的信息来填充 URL 到方法的映射。
- 在处理请求时,使用映射路由到预期的方法。
理解流程的一个简单技巧(是的,Java 有时太神奇了)是安装断点并查看调用堆栈。