简体   繁体   English

Spring 编译时和运行时注解的区别

[英]Difference between compile time & run time annotations of Spring

In a recent interview for a Java developer , I met with a question on spring annotation:最近在一个Java开发者的面试中,遇到了一个关于spring注解的问题:

What is the difference between compile time and runtime annotations in spring? spring 编译时和运行时注解有什么区别?

Is there a concept like this?有这样的概念吗?

An answer would be appreciated.一个答案将不胜感激。

There is nothing like compile time or run-time annotations.没有什么比编译时或运行时注释更好的了。

They're markers that are read different API.它们是读取不同 API 的标记。 Based on how they are processed, one can call them compile/run-time annotation.根据它们的处理方式,可以将它们称为编译/运行时注释。

Java provides two different options for processing source code annotations. Java 提供了两种不同的选项来处理源代码注释。 One of them is the annotation processing API used in compile time, and the other is the Reflection API used in runtime.一个是编译时使用的注解处理API,另一个是运行时使用的反射API。 eg @Override annotation is read by compiler.例如@Override注释由编译器读取。

https://ieeexplore.ieee.org/document/7321547/ https://ieeexplore.ieee.org/document/7321547/

Somewhat similar to your question.有点类似于你的问题。 Have a look at it: When are Java annotations executed?看一看: Java注解什么时候执行?

Annotation are a generic way to decorate classes/properties or methods.注释是装饰类/属性或方法的通用方法。 They have nothing to do with compile time or run time.它们与编译时或运行时无关。 However, the classes that use annotation to do their work can do this at compile time or at run time.但是,使用注解来完成工作的类可以在编译时或运行时执行此操作。

Example: Spring AOP.示例:Spring AOP。 For AOP, you decorate your classes with @Aspect annotations and depending on type of proxy you want to create, the weaving can happen compile time doing byte code modification or at run time.对于 AOP,您可以使用 @Aspect 批注装饰您的类,并且根据您要创建的代理类型,编织可以在编译时进行字节码修改或在运行时发生。 You can find more details via ajc compiler/JDK dynamic proxies/CGLib proxies.您可以通过 ajc 编译器/JDK 动态代理/CGLib 代理找到更多详细信息。

Colloquially, when someone refers to a "compile-time" or "runtime" annotation in Java, they are likely referring to the annotation's assigned (or implied) retention policy.通俗地说,当有人在 Java 中提到“编译时”或“运行时”注释时,他们很可能指的是注释的分配(或暗示)保留策略。 So to answer the interview question requires knowledge of Java annotations in general, and the specific annotations defined by the Spring framework.所以回答面试问题需要了解Java注解的一般知识,以及Spring框架定义的具体注解。 With regard to Java, JLS 15 §9.6.4.2 says:关于 Java, JLS 15 §9.6.4.2说:

Annotations may be present only in source code, or they may be present in the binary form of a class or interface.注解可能只出现在源代码中,也可能以类或接口的二进制形式出现。 An annotation that is present in the binary form may or may not be available at run time via the reflection libraries of the Java SE Platform.通过 Java SE 平台的反射库,以二进制形式存在的注释在运行时可能可用,也可能不可用。 The annotation type java.lang.annotation.Retention is used to choose among these possibilities.注释类型java.lang.annotation.Retention用于在这些可能性中进行选择。

The RetentionPolicy enum offers three possibilities (ordering mine): RetentionPolicy 枚举提供了三种可能性(订购我的):

SOURCE - Annotations are to be discarded by the compiler. SOURCE - 编译器将丢弃注释。

CLASS - Annotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time. CLASS - 注释将由编译器记录在类文件中,但不需要在运行时由 VM 保留。

RUNTIME - Annotations are to be recorded in the class file by the compiler and retained by the VM at run time, so they may be read reflectively. RUNTIME - 注释将由编译器记录在类文件中,并在运行时由 VM 保留,因此可以反射性地读取它们。

All annotations are accessible if you have access to the source code, but annotations with SOURCE retention will never appear in the compiled bytecode;如果您有权访问源代码,则所有注释都可以访问,但带有SOURCE保留的注释永远不会出现在编译后的字节码中; they will never appear to any tools that read the compiled form of the class -- such as when compiling a downstream application -- and without bytecode there is nothing to load at runtime, either.它们永远不会出现在任何读取类的编译形式的工具中——例如在编译下游应用程序时——并且如果没有字节码,则在运行时也无法加载任何内容。

When an annotation has CLASS retention, the annotation has a presence in the compiled bytecode where the annotation is used -- so that use can be examined by tools that operate directly on bytecode.当注释具有CLASS保留时,该注释存在于使用该注释的已编译字节码中——因此可以通过直接对字节码进行操作的工具来检查该使用情况。 Examples include compilers, code quality tools (eg Spotbugs), or runtime code generators (ASM, javassist, Byte-Buddy, etc.).示例包括编译器、代码质量工具(例如 Spotbugs)或运行时代码生成器(ASM、javassist、Byte-Buddy 等)。 While the annotation information is present in the bytecode ( *.class file), the JVM does not load this information at runtime.虽然注释信息存在于字节码( *.class文件)中,但 JVM不会在运行时加载此信息。

Finally, an annotation with RUNTIME retention has all of the capabilities above, but is also loaded into the JVM at runtime and can be discovered using the Reflection APIs from within running programs.最后,带有RUNTIME保留的注释具有上述所有功能,但也会在运行时加载到 JVM 中,并且可以在运行的程序中使用反射 API 发现。

If retention is not explicitly defined for an annotation, it defaults to RetentionPolicy.CLASS .如果未为注释显式定义RetentionPolicy.CLASS ,则默认为RetentionPolicy.CLASS

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM