A note

Java annotations, also known as Java annotations, are an Annotation mechanism introduced in JDK1.5. Is a form of metadata that provides data about a program that is not part of the program itself. Annotations have no direct effect on the actions of the code they annotate

Binary annotations

The annotation class can also use other annotation declarations when defining annotations. An annotation class that annotates an annotation type is called a meta-annotation. The annotation of the declaration allows the @target declaration to be applied to which nodes; The Retention level is stated by @retention. The retention levels are as follows.

  • The annotations for the retentionPolicy.source tag remain only at the SOURCE level and are ignored by the compiler
  • Annotations of the RetentionPolicy.class tag are retained by the compiler at compile time, but ignored by the Java Virtual Machine (JVM).
  • The annotations for the RetentionPolicy.Runtime tag are reserved by the JVM so that the RUNTIME environment can use it

SOURCE < RUNTIME < RUNTIME < RUNTIME < RUNTIME < RUNTIME < RUNTIME < RUNTIME < RUNTIME

Three application scenarios of annotations

There are naturally different scenarios for the use of annotations, depending on their retention level. Annotations work on source code, bytecode, and runtime, based on the three different retention levels of annotations

APT annotation processor

APT is called “Anotation Processor Tools”, which means annotation Processor. As the name suggests, it is used to handle annotations. The Java source document must be compiled by JavAC and translated into a bytecode Class file that the VM can load and parse. The annotation processor is a tool that comes with Javac and is used to scan annotation information at compile time. You can register your own annotation handlers for certain annotations. The registered annotation handler is invoked by the JavAC and passes the annotation information to the annotation handler for processing.

Annotation handlers are the most widely used scenario for annotations. Annotation processors are found in Glide, EventBus3, Butterknifer, Tinker, ARouter, and many other commonly used frameworks. However, you may find that these frameworks define annotations not at the SOURCE level, but at the CLASS level. Remember :CLASS contains SOURCE, RUNTIME contains SOURCE, and CLASS

APT usage details

  1. Create a new Module with a new annotation

Notice that this is java-Library

package com.base.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @ Target ({ElementType. TYPE, ElementType METHOD}) @ Retention (RetentionPolicy. SOURCE) public @ interface Route {/ * * * routing path, Identifies a routing node */ String path(); */ String group() default ""; }Copy the code
  1. Create a new Module to create an annotation handler
package com.base.compiler.processor; import com.base.annotation.Route; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeSpec; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.Writer; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.element.Element; import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.tools.Diagnostic; import javax.tools.JavaFileObject; //1. Here is APT annotation handler associated with defined annotations @SupportedAnnotationTypes({"com.base.basejavapro.annotation.Route","com.base.annotation.Route"}) public class RouteProcessor extends AbstractProcessor { private Filer mFiler; @Override public synchronized void init(ProcessingEnvironment processingEnvironment) { super.init(processingEnvironment); mFiler = processingEnv.getFiler(); } @override public Boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv) { Messager messager = processingEnv.getMessager(); Messenger. PrintMessage (Diagnostic. Kind. NOTE, "= = = = = = = = = = = = = RouteProcessor = = = = = = = = = = = = = = = = = = :" + set. The size ()); // Compile-time log print Set<? extends Element> routeElements = roundEnv.getElementsAnnotatedWith(Route.class); For (Element Element: routeElements) {// 4. Route Route = element.getannotation (route.class); String path = route.path(); String group = route.group(); String newClassName = path + "$$Hx"; StringBuilder Builder = new StringBuilder().append("package com.hongx.processor.auto; \n\n") .append("public class ") .append(newClassName) .append(" {\n\n") // open class .append("\tpublic String getMessage() {\n") // open method .append("\t\treturn ""); builder.append(path).append(group).append(" ! \n"); builder.append(""; \n") // end return .append("\t}\n") // close method .append("}\n"); // close class try { JavaFileObject source = mFiler.createSourceFile("com.hongx.processor.auto."+newClassName); Writer writer = source.openWriter(); writer.write(builder.toString()); writer.flush(); writer.close(); } catch (IOException e) { } if (! set.isEmpty()) { createRoute(mFiler,newClassName,path); } } return false; JavaPoet public static void createRoute(Filer Filer,String className,String path) {// Generated using the main MethodSpec method MethodSpec main = methodSpec.methodBuilder ("getMessage") .addStatement("return $S",path) .build(); TypeSpec = TypeSpec. ClassBuilder (className) // The name of the main class .modifier (Modifier.public, Modifier.final).addMethod(main).addJavadoc(" Comment code blocks ").build(); try { JavaFile javaFile = JavaFile.builder("com.javapoet.processor.auto", typeSpec) .build(); /** * write code to console */ javafile.writeto (system.out); /* FastEc\latte_compiler\ SRC \main\ Java */ javafile.writeto (filer); } catch (Exception e) { e.printStackTrace(); }}}Copy the code

3. Manually create a configuration file javax.mail. The annotation. Processing. The Processor

In the main directory to create the resources/meta-inf/services/javax.mail annotation. Processing. The Processor file Its content is the full class name custom annotation processor

4. Run the result through compilation, in the compilation directory generated object files 1, 2, and

stepThe execution result

Code has been uploaded to Github

The code download