Explicación detallada de la anotación @inherited

1 [Pregunta suscitada]

En un proyecto Springboot, generalmente hay una clase de inicio, y la clase de inicio generalmente tiene una anotación llamada @SpringBootApplication (como se muestra en la figura a continuación), y esta anotación es la anotación principal de la clase de inicio del proyecto Springboot.

Abrimos el código fuente de la anotación @SpringBootApplication, podemos ver que hay una anotación @Inherited en el código fuente, entonces, ¿cuál es la función de esta anotación?

2【@código fuente heredado】

Antes de comprender la función de la anotación, es posible que deseemos echar un vistazo a la explicación en inglés y la definición del código fuente de la anotación, que será más conducente a nuestra comprensión de la anotación.

(2.1) traducción heredada

 En primer lugar, echemos un vistazo a la traducción (de la traducción de Baidu), podemos ver que @inherited tiene el significado de "herencia" y "sucesión".

(2.2) @heredar código fuente

Luego, abrimos el código fuente de heredado y podemos ver:

(1) La anotación actúa sobre todo el programa en ejecución ( @Retention(RetentionPolicy.RUNTIME );

(2) Esta anotación solo puede modificar anotaciones ( @Target({ElementType.ANNOTATION_TYPE}) ), por lo que es una metaanotación.

 Después de comprender la situación anterior, podemos explorar más a fondo la anotación @inherited.

3【Ejemplo】

Dado que es una anotación sobre "herencia", podemos pensar que también existe una relación de herencia entre las clases de Java. También podríamos crear dos clases, dejar que sean una relación padre-hijo, y luego crear dos anotaciones para actuar sobre la arriba, la única diferencia entre las dos anotaciones es la presencia o ausencia de la decoración @Inherited.

Creamos la clase padre Padre y la clase hijo Hijo como clases experimentales.

(3.1) Clase padre

(3.2) Clase hijo (clase padre heredero)

 Además, personalizamos dos anotaciones más, @HasInherited y @NoInherited, para verificar el resultado, la primera anotación contiene la anotación @Inherited, la última viceversa.

Dado que la definición de la anotación debe especificar el alcance de la acción y el ciclo de vida de la acción, también podríamos especificar que ambas anotaciones actúan en la clase y en todo el código que ejecuta el ciclo de vida, de modo que la única diferencia entre los dos es el presencia o ausencia de la anotación @Inherited.

(3.3) @HasInherited (con anotación @Inherited)

(3.4) @NoInherited (sin anotación @Inherited)

 

 4【Verificación de prueba】

(4.1) Crear clase de prueba de prueba

Escribamos otra clase de prueba Prueba para obtener toda la información de anotación en las clases experimentales (Padre e Hijo).

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) Validación con anotación @Inherited

Primero, solo anotamos la clase principal con @HasInherited, la subclase no la procesa y luego ejecutamos la clase de prueba Test.

@HasInherited
public class Father {

}

La consola final imprime lo siguiente:

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

 (4.3) Sin validación de anotación @Inherited

Solo anotamos la clase principal con @NoInherited, la subclase no la procesa y luego ejecuta la clase de prueba Test.

@NoInherited
public class Father {

}

La impresión final de la consola es la siguiente:

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

(4.4) Conclusión

Después de la demostración anterior, no es difícil para nosotros llegar a la conclusión final.

Conclusión: si una anotación modificada por la anotación @Inherited actúa sobre una clase, sus subclases pueden heredar la anotación. Por el contrario, si una anotación no es modificada por la anotación @Inherited, su alcance solo puede ser la clase actual y sus subclases no se pueden heredar.

5. [Modificar la clase de inicio de Springboot]

Dado que la anotación @SpringBootApplication también contiene la anotación @Inherited, para la conclusión anterior, también podríamos intentar modificar la clase de inicio de Springboot. Podemos escribir una subclase para heredar la clase de inicio original y eliminar el método mian de inicio original. , agregue a la subclase para ver si puede iniciarse correctamente?

(5.1) Antes de modificar la clase de inicio de Springboot

La clase de inicio se muestra en la figura:

Comience a imprimir de la siguiente manera:

(5.2) Después de modificar la clase de inicio de Springboot

La clase de inicio original (solo se conserva la anotación @SpringBootApplication)

Clase de subinicio (sin anotaciones)

 Comience a imprimir de la siguiente manera:

 Se puede ver que, de hecho, se inició correctamente, lo que también verifica nuestro razonamiento.

6【Resumen】

Cuando definimos una anotación que actúa sobre una clase en el futuro, si queremos que la anotación también actúe sobre sus subclases, podemos usar @Inherited para modificarla.

 

Supongo que te gusta

Origin blog.csdn.net/sunnyzyq/article/details/119736442
Recomendado
Clasificación