Java Annotation Processor-Five minute QuickStart __java

Source: Internet
Author: User
Tags reflection
Basic Concepts

Java annotations (Annotation) are divided into two categories: annotations that are processed at compile time (Compile times) and annotations that run at runtime (Runtime) through the reflection mechanism. This article will focus on the annotations that are processed at compile time (Compile times), about the annotations that run through the reflection mechanism at run time (Runtime), relatively simple here do not introduce you can find information to learn.

The annotation processor (Annotation Processor) is a tool for javac that scans and processes annotations (Annotation) at compile time. You can customize annotations and generate new Java files at compile time.

When Java 5 first introduced annotations, the API for the annotation processor was not mature or standardized. Processing annotations requires a separate tool named APT (that is, annotation Processor Tool, annotation processor tool), and a mirror API included in the Com.sum.mirror package. Apt needs to use the mirror API to customize the processor.

Starting with Java 6, the annotation processor has been standardized and incorporated into the standard library through JSR 269, and the APT tool has been seamlessly integrated into the Java compiler tool JAVAC. Java 6 provides an abstract class javax.annotation.processing.AbstractProcessor that has implemented common functionality, and also provides Javax.lang.model packages. Annotation Processor API

If we want to develop a note processor ourselves, we need to inherit from Abstractprocessor, as follows:

package com.bytebeats.apt; public class Exampleprocessor extends Abstractprocessor {@Override public synchronized void init (processingenvir Onment env) {} @Override public boolean process (SET<? extends typeelement> annoations, roundenvironment env  {} @Override Public set<string> getsupportedannotationtypes () {set<string> annotataions =
        New Linkedhashset<string> (2);
        Annotataions.add (Factory.class.getCanonicalName ());
    return annotataions;
    @Override public SourceVersion getsupportedsourceversion () {return sourceversion.latestsupported (); }

}

WHERE Init (processingenvironment env): Each annotation processor class must have an empty constructor. The init () method is called by the annotation processing tool and the Processingenviroment parameter is entered. Processingenviroment offers a lot of useful tools like elements, types and filer. Process (SET< extends typeelement> annotations, roundenvironment
ENV): This is one of the most important methods where you write your code for scanning, evaluating, and processing annotations, as well as generating Java files. The input parameter roundenviroment allows you to query for annotated elements that contain specific annotations. Getsupportedannotationtypes (): The annotation processor is registered to which annotations. Its return value is a collection of strings containing the legal full name of the annotation type that the processor wants to process. Getsupportedsourceversion (): Used to specify the Java version you are using. Usually here returns sourceversion.latestsupported (). However, if you have enough reason to support only Java 7, you can also return to sourceversion.release_7.


Note:
In Java version 6 and above, the Getsupportedannotationtypes () method and the Getsupportedsourceversion () Methods can be replaced by @supportedannotationtypes annotations and @supportedsourceversion annotations, respectively, as follows:

Package com.bytebeats.apt;

@SupportedAnnotationTypes ({"Com.bytebeats.apt.Factory"})
@SupportedSourceVersion (sourceversion.release_7) Public
class Exampleprocessor extends Abstractprocessor {

    @Override public
    synchronized void Init ( Processingenvironment env) {}

    @Override public
    boolean process (set<? extends Typeelement> annoations, Roundenvironment env) {}

}
Implement a note processor 1. Define Annotations
Package com.bytebeats.apt;

Import Java.lang.annotation.ElementType;
Import java.lang.annotation.Retention;
Import Java.lang.annotation.RetentionPolicy;
Import Java.lang.annotation.Target;

/**
 * @author Ricky Fung
 * @date 2016-12-28 11:26
/@Target ({elementtype.type})
@Retention (Retentionpolicy.class)
Public @interface Bean {
    String ID () default "";
}

The retention annotation has an attribute value that accepts the value of the Retentionpolicy type, Retentionpolicy is an enumeration type with 3 values: SOURCE, CLASS, RUNTIME
* Retentionpolicy.source: Indicates that the information on the compile-time annotation is discarded by the compiler and is not left in the class file.
The annotation information will only remain in the source file;
* Retentionpolicy.class: Indicates compile-time annotation information is kept in the CLASS file (bytecode file), but will not be read by the virtual machine at run time;
* Retentionpolicy.runtime: Indicates compile-time annotation information is kept in the class file (bytecode file), and will be retained by the virtual machine at runtime, can be reflected in the way read; 2. Write annotation processor

Custom processors need to inherit from Abstractprocessor, as follows:

Package com.bytebeats.apt;
Import Com.google.auto.service.AutoService;
Import javax.annotation.processing.*;
Import javax.lang.model.SourceVersion;
Import javax.lang.model.element.Element;
Import Javax.lang.model.element.ElementKind;
Import javax.lang.model.element.TypeElement;
Import javax.lang.model.util.Elements;
Import Javax.lang.model.util.Types;
Import javax.tools.Diagnostic;
Import Java.util.LinkedHashSet;

Import Java.util.Set; 
    /** * Annotation Processor * * @author Ricky Fung * @date 2016-12-28 11:19/public class Beanprocessor extends Abstractprocessor {
    Private Types typeutils;
    Private Elements elementutils;
    Private Filer Filer;

    Private Messager Messager;
        @Override public synchronized void init (Processingenvironment processingenv) {super.init (processingenv);
        Typeutils = Processingenv.gettypeutils ();
        Elementutils = Processingenv.getelementutils ();
        filer = Processingenv.getfiler (); Messager = Processingenv.getmessager ();  @Override public set<string> getsupportedannotationtypes () {set<string> annotataions = new
        Linkedhashset<string> (2);
        Annotataions.add (Factory.class.getCanonicalName ());
    return annotataions;
    @Override public SourceVersion getsupportedsourceversion () {return sourceversion.latestsupported ();

        @Override public Boolean process (SET&LT; extends typeelement> annotations, roundenvironment roundenv) { For (Element Element:roundEnv.getElementsAnnotatedWith (Bean.class)) {if (Element.getkind ()!= Ele 
                Mentkind.class) {error (element, "only classes can is annotated with @%s", Factory.class.getSimpleName ());
            return true;
    return false;
                }/**log**/private void error (Element e, String msg, Object ... args) {messager.printmessage ( Diagnostic.Kind.ERROR, String.formAt (msg, args), E);
 }
}

In Init () we get the following reference: Elements: A tool class for handling element; Types: A tool class for handling typemirror; Filer: As this name shows, use Filer you can create files;

During the annotation process, we scan all Java source files. Each part of the source code is a specific type of element. In other words: an element represents a program's elements, such as a package, class, or method. Each element represents a static, language-level widget.

The element represents the source code, and its subclasses have these: Packageelement: Package name Typeelement: Class variableelement: Variable executableelement: Method

A simple Java class is used to illustrate:

Package com.bytebeats;    Packageelement public

class Car {        //typeelement

    private double;      Variableelement
    private Wheel Wheel;  Variableelement public Car

    () {}    //executeableelement public

    void Setwheel (  //Executeableelement
                     Wheel Wheel   //Typeelement
                     ) {
        this.wheel = Wheel;
    }
}

At this point must look at the source code, it is only structured text, it is not available to run. You can imagine it just like the XML file you're going to parse (or the abstract syntax tree in the compiler). Like the XML interpreter, there are some elements that resemble Dom. You can navigate from one element to its parent or child element. 3. Register Note Processor

How to register your processor in the Javac? The Resources/meta-inf/services directory in the current project needs to create a new special file Javax.annotation.processing.Processor, and the contents of the file are to declare your processor.

The final package generates the. jar file directory structure as follows:
-com
--Bytebeats
--Apt
---Factoryprocessor
-Meta-inf
--Services
--Javax.annotation.processing.Processor


The content of the Javax.annotation.processing.Processor file is the legal full name list for the annotation processor, with each element being broken into lines:


In addition, using Google's Auto-service can automatically generate meta-inf/services/javax.annotation.processing.processor files, as follows:

@AutoService (processor.class) Public
class Factoryprocessor extends Abstractprocessor {
    private Types Typeutils;
    Private Elements elementutils;
    Private Filer Filer;
    Private Messager messager;

    @Override public
    synchronized void init (Processingenvironment processingenv) {
        super.init (processingenv);
        Typeutils = Processingenv.gettypeutils ();
        Elementutils = Processingenv.getelementutils ();
        filer = Processingenv.getfiler ();
        Messager = Processingenv.getmessager ();
    }

    @Override Public
    Boolean process (set< extends typeelement> annoations, roundenvironment env) {

    }
}

Need to add Maven dependencies:

<dependency>
    <groupId>com.google.auto.service</groupId>
    <artifactId> auto-service</artifactid>
    <version>1.0-rc2</version>
</dependency>
Source Download

Point This download source code: Https://github.com/TiFG/annotation-in-action

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.