Detailed explanation of @inherited annotation

1 [Question elicited]

In a Springboot project, there is usually a startup class, and the startup class usually has an annotation named @SpringBootApplication (as shown in the figure below), and this annotation is the core annotation of the Springboot project startup class.

We open the @SpringBootApplication annotation source code, we can see that there is an @Inherited annotation in the source code, so what is the function of this annotation?

2【@inherited source code】

Before understanding the function of the annotation, we may wish to take a look at the English explanation and source code definition of the annotation, which will be more conducive to our understanding of the annotation.

(2.1) inherited translation

 First of all, let's look at the translation (from Baidu translation), we can see that @inherited has the meaning of "inheritance" and "succession".

(2.2) @inherite source code

Then, we open the source code of inherited and we can see:

(1) The annotation acts on the entire program running ( @Retention(RetentionPolicy.RUNTIME );

(2) This annotation can only modify annotations ( @Target({ElementType.ANNOTATION_TYPE}) ), so it is a meta-annotation.

 After understanding the above situation, we can further explore the @inherited annotation.

3【Example】

Since it is an annotation about "inheritance", we can think that there is also an inheritance relationship between Java classes. We might as well create two classes, let them be a parent-child relationship, and then create two annotations to act on the class. Above, the only difference between the two annotations is the presence or absence of @Inherited decoration.

We create the parent class Father and the child class Child as experimental classes.

(3.1) Father class

(3.2) Child class (inheriting Father class)

 In addition, we customize two more annotations, @HasInherited and @NoInherited, to verify the result, the former annotation contains the @Inherited annotation, the latter vice versa.

Since the annotation definition needs to specify the scope of action and the life cycle of the action, we might as well specify that both annotations act on the class and in the entire code running life cycle, so that the only difference between the two is the presence or absence of the @Inherited annotation.

(3.3) @HasInherited (with @Inherited annotation)

(3.4) @NoInherited (no @Inherited annotation)

 

 4【Test verification】

(4.1) Create Test test class

Let's write another test class Test to get all the annotation information on the experimental classes (Father and Child).

package com.test.inherited;

import java.lang.annotation.Annotation;

public class Test {

    public static void main(String[] args) {
        // 打印父类注解信息
        Annotation[] fatherAnnotations = Father.class.getAnnotations();
        System.out.println("------- 父类 Father 信息 --------");
        System.out.println("父类注解个数:" + fatherAnnotations.length);
        for (Annotation fa : fatherAnnotations) {
            System.out.println(fa.annotationType().getSimpleName());
        }
        // 打印子类注解信息
        Annotation[] childAnnotations = Child.class.getAnnotations();
        System.out.println("------- 子类 Child 信息 --------");
        System.out.println("子类注解个数:" + childAnnotations.length);
        for (Annotation ca: childAnnotations) {
            System.out.println(ca.annotationType().getSimpleName());
        }
    }

}

 (4.2) Validation with @Inherited annotation

First, we only annotate the parent class with @HasInherited, the subclass does not process it, and then execute the test class Test.

@HasInherited
public class Father {

}

The final console prints the following:

------- 父类 Father 信息 --------
父类注解个数:1
HasInherited
------- 子类 Child 信息 --------
子类注解个数:1
HasInherited

 (4.3) No @Inherited annotation validation

We only annotate the parent class with @NoInherited, the subclass does not process it, and then executes the test class Test.

@NoInherited
public class Father {

}

The final console print is as follows:

------- 父类 Father 信息 --------
父类注解个数:1
NoInherited
------- 子类 Child 信息 --------
子类注解个数:0

(4.4) Conclusion

After the above demonstration, it is not difficult for us to come to the final conclusion.

Conclusion: If an annotation modified by the @Inherited annotation acts on a class, its subclasses can inherit the annotation. Conversely, if an annotation is not modified by the @Inherited annotation, its scope can only be the current class, and its subclasses cannot be inherited.

5. [Modify the Springboot startup class]

Since the @SpringBootApplication annotation also contains the @Inherited annotation, for the above conclusion, we might as well try to modify the Springboot startup class. We can write a subclass to inherit the original startup class and remove the original startup mian method. , add it to the subclass to see if it can start successfully?

(5.1) Before modifying the Springboot startup class

The startup class is shown in the figure:

Start printing as follows:

(5.2) After modifying the Springboot startup class

The original startup class (only the @SpringBootApplication annotation is retained)

Sub-startup class (without any annotations)

 Start printing as follows:

 It can be seen that it is indeed started OK, which also verifies our reasoning.

6【Summary】

When we define an annotation that acts on a class in the future, if we want the annotation to also act on its subclasses, we can use @Inherited to modify it.

 

Guess you like

Origin blog.csdn.net/sunnyzyq/article/details/119736442