Annotations have been a life skill for Java developers since SpringBoot, and we spend most of our time coding for annotations, which can save us a lot of time. With so many annotations, have we looked at how annotations are implemented? So this article is mainly about the operation of annotations, their own implementation of a annotation to experience the realization of the principle of annotations, annotations are not particularly sophisticated things, master the natural understand.

The rationale for annotations

Annotations are intended to be used as annotations: you can place a special tag on classes, field variables, methods, interfaces, etc., to pave the way for future work such as code generation, data validation, resource integration, etc. So annotations are for marking, and once annotations are annotated to the code, they can then be dynamically retrieved at run time, combined with Java’s powerful reflection mechanism, to perform a lot of other logic and automate the work we want. So, reflex mechanisms are important.

Example use of annotations

Suppose we now have a Person class that is passed in as a parameter and we want to check the parameter:

public class Person {
    private Integer id;
    private String name;
    private Integer age;
    
    //Getter and Setter
}
Copy the code

If there are no annotations, then we need to write a long if else check like this:

Public String addPerson(Person){if(Person == null){return "Parameter null "; } if(person.getId() == null || "".equals(person.getId())){ return "Person's id is null"; } if(person.getName() == null || "".equals(person.getName())){ return "Person's name is null."; } if(person.getName().length() < 3){ return "Person's name length must lager 3."; } if(person.getAge() == 0){ return "Person's age is null."; } if(person.getAge() <= 0 || person.getAge() >= 150){ return "Person's age error."; }}Copy the code

So, see how to use annotations to validate these parameters:

Public class Person {@notnull (message = "incoming Id null ") @notempty (message =" incoming Id null ") private String Id; @notnull (message = "incoming Name null ") @notempty (message =" incoming Name null string ") @length (min = 3, Max = 30, Message = "Name must be between 3 and 30 ") private String name; @min (value = 0, message = "Age should be between 0 and 150 ") @max (value = 150, Message = "age should be between 0 and 150 ") private Integer age; //Getter and Setter. }Copy the code

The implementation of the @length annotation

In this article, we will implement the @length annotation. This annotation is learned, and all other annotations are the same:

Step1. Define annotation @length

import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @target ({elementtype.field}) @retention (retentionPolicy.runtime) public @interface Length{// Maximum allowed string Length int min(); // Maximum allowed string length int Max (); // Custom error message String errorMsg(); }Copy the code

1. Defining an annotation is a bit like defining an interface, except that it is preceded by an @ sign

2. Annotated member variables can only be enumerated with primitive, String, or enum types, such as int, but Integer wrapping types cannot

3. The above @target and @Retention notes added to the definition of annotations are called “meta-annotations”. Meta-annotations are specially used to add annotations to annotations

4. @target (XXX) specifies where the custom annotation can be used, for example:

  • Elementtype. FIELD: Indicates that custom annotations can be used for class variables
  • Elementtype. METHOD: Indicates that custom annotations can be applied to class methods
  • Elementtype. TYPE: Indicates that custom annotations can be used with the class itself, interface, or enum TYPE
  • In fact, there are many more, if you can’t remember the words or suggest to use now check

5, @Retention (XXX) use a description of the lifetime of your custom annotations, e.g. :

  • @Retention (retentionPolicy.runtime) : Indicates that annotations are retained until RUNTIME, and therefore can be retrieved through reflection
  • @Retention (retentionPolicy.class) : Indicates that annotations are compiled by the compiler into the CLASS file but ignored at runtime
  • @Retention (retentionPolicy.source) : Indicates that annotations are valid only in the SOURCE file and will be ignored at compile time

In general, if you need to dynamically retrieve annotation information at RUNTIME, use RUNTIME, as in this article.

Step2. Get the annotations and validate them

What do I do when I want to get the information contained in the annotation generation at run time? We use Java’s reflection knowledge! Validate () : validate() : validate() : validate() : validate() : validate()

public class LengthValidator { public static String validateField(Object object) throws IllegalAccessException { // Field[] fields = object.getClass().getDeclaredFields(); Field[] fields = object.getClass(). For (Field Field: Fields){// if judge: Check: is @ Length annotations if marked on the field (field. IsAnnotationPresent (Length. Class)) {/ / by reflecting access to this field on the annotation of the @ Length details of Length Length = field.getAnnotation(Length.class); // Let's see the private variable field.setaccessible (true) when reflected; Int value = ((String)field.get(object)).length(); / / will be the value of the actual field and annotations of tag values compared the if (value < length. The min () | | value > length. The Max () {return length. The errorMsg (); } } } return null; }}Copy the code

Step3. Use custom annotations

At this point, the Person class just needs to add this annotation

public class Person { private String id; @length (min = 3, Max = 30, errorMsg = "Name must be between 3 and 30 ") private String name; private Integer age; //Getter and Setter }Copy the code

Then use:

public class AnnotationTest {
    public static void main(String[] args) throws IllegalAccessException {
        Person person = new Person();
        person.setName("13");
        person.setAge(10);
        person.setId("001");

        String validateField = LengthValidator.validateField(person);
        if(validateField == null)
            System.out.println(person);
        else
            System.out.println(validateField);
    }
}
Copy the code