[Java Study Notes-Basic Articles] About annotation (annotation) programming

foreword

Looking at the code I wrote before today, I found that my understanding of annotations is not very thorough. I often selectively ignore the exploration of annotation implementation, so I searched for information and studied.

what is annotation

implementation format

From the code, we know that the implementation format of annotations is:

public @interface MyAnnotation{
    
    
	属性列表;
}

So we have the first intuition that the annotation may be an interface . By querying the information (you can use decompilation software), in fact @interface is the inheritance of the annotation interface from the custom interface, and @interface is actually a syntactic sugar.

import java.lang.annotation.Annotation;

public interface MyAnnotation extends Annotation{
    
    
	属性列表;
}
utilized location

Classes, methods, member variables, formal parameter locations.

Classification

From different perspectives, we can classify annotations in different ways, but after knowing the implementation principles of annotations, we will understand that usage and implementation methods are actually the same thing.

  • source
  1. JDK annotations: generally used as annotations at compile time, such as @Override, which we are most familiar with.
  2. Third-party framework annotations
  3. custom annotation
  • Operating mechanism (retention policy)
    @Retention({
          
          保留策略})
    public @interface MyAnnotation{
          
          
    	属性列表;
    }
    
  1. Source code (SOURCE) annotations: Annotations only exist in the source code, and will not exist when compiled into .class files, that is to say, they can only play the role of "seeing".
  2. Compilation (CLASS) annotations: annotations exist in both source code and .class files (JDK’s own annotations are all compile-time annotations), and are generally used for syntax verification.
  3. Runtime (RUNTIME) annotation: It still works during the runtime phase, and even affects the runtime annotation (@Autowired belongs to the runtime annotation). Third-party frameworks and custom annotations generally adopt the runtime retention strategy, which can realize dependency injection and aspect programming and other functions.
  • Meta-annotations
    Actually above, we have seen a meta-annotation (@Retention). Meta-annotations are annotations added to annotations that describe annotations. There are 5 in total.
  1. @Documented
    will display the @Documented annotation when javadoc is generated.
  2. @Target (key)
    defines the position of action, Method, Class, etc.
  3. @Inherited
    is annotated by @Inherited to modify a parent class. If its subclass is not modified by other annotations, its subclass also inherits the annotation of the parent class.
  4. @Retention (key)
    The retention policy annotation above affects the effect of the annotation.
  5. @Repeatable (not important)
    The @Repeatable annotation is a meta-annotation used to declare other types of annotations to indicate that the declared annotations are repeatable. The value of @Repeatable is another annotation, which can contain this repeatable annotation by the value of this other annotation.

how to use

Let's first understand the superficial use of annotations. simplest,

Using custom annotations is divided into three steps: defining annotations, using annotations, and reading annotations.
insert image description here
Excerpt from: https://www.zhihu.com/question/47449512/answer/658228092

As long as we firmly grasp these three steps, we can master the use of annotations.

Definition Annotation

Because, the basic function of the annotation is to judge how to execute the annotated code block according to the value in the annotation. Therefore, when defining annotations, in addition to adding annotations based on functions, it is also necessary to write appropriate method names based on business meaning.

For example, if we want to write a lock annotation:

@Documented
@Retention(RUNTIME)
@Target({
    
    TYPE, METHOD})
public @interface Lock {
    
    
	//输锁名称
    String lockName();
	//被锁值
    String key();
    //锁级别
    int level();
	//异常
    String exception() default "";
}

In an annotation, the types that can be returned are: basic data types, String, enum, Class, other annotations, and one-dimensional arrays of the former.

Note: If there is no default, parameters must be entered when using it.

Use annotations

Annotation In the place of this annotation, the parameter must be entered in the parameter.

Tips : If there is only one function in the annotation, although it can be directly entered as a parameter without adding the function name when using it, I personally recommend that for custom annotations, write the full function name when entering the parameter to enhance the readability of the code.

read comments

Let's think about it first, if we implement a method of reading annotations ourselves, how should we implement it?

There are only two I can think of right now:

  1. Find annotations in strings or bytecode files: this judgment is not easy to write, and complex strings cannot be processed.
  2. Obtain annotations on classes, methods, and member variables through reflection.

Anyone with a discerning eye can see that 2 is much more reliable than 1, and it is also easy to implement.

The easiest way to read:

    public static void main(String[] args) throws NoSuchMethodException {
    
    
        Class<Module> modelClazz = Module.class;
        Method method = modelClazz.getMethod("lock", null);
        Lock annotationLock = method.getAnnotation(Lock.class);
        //获取注解在 lock 方法上的 value
        String lockName = annotationLock.lockName();
    }

This is also the basic implementation principle of framework annotations , because to obtain the specific code blocks of annotations, it is generally necessary to scan the package.

For aspect programming , after introducing the dependency on aspectj, then we have a simpler calling method:

	//切面代码节选
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
    
    
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Lock lock = signature.getMethod().getAnnotation(Lock.class);
        lock.lockName();
    }

For specific knowledge about aspect programming and joinpoint, please refer to:

https://blog.csdn.net/qq_15037231/article/details/80624064

The role of annotations

So far we can summarize the role of annotations.

  • Programming Tips
    Annotations whose retention policy is source code are generally suggestive annotations, such as @deprecated.
  • It is used for faceting to reduce duplication of code.
    The retention strategy is the annotation of operation, and zero intrusion changes the operation effect of the function. It is generally used for repetitive functions, such as log output, data format verification, etc.
  • To reduce configuration information, the project structure
    is mainly for the springboot framework. Because annotations can take values, it also supports inputting configuration information while setting default configuration information.
  • Format check
    is generally a syntax check of the code, which exists in the annotation package of jdk, such as @Override.

Guess you like

Origin blog.csdn.net/weixin_43742184/article/details/112767574