在Spring Boot中大量使用了@Inherited注解。我们来了解一下这个注解的用法,注解的源码:
packagejava.lang.annotation;/*** Indicates that an annotation type is automatically inherited. If
* an Inherited meta-annotation is present on an annotation type
* declaration, and the user queries the annotation type on a class
* declaration, and the class declaration has no annotation for this type,
* then the class's superclass will automatically be queried for the
* annotation type. This process will be repeated until an annotation for this
* type is found, or the top of the class hierarchy (Object)
* is reached. If no superclass has an annotation for this type, then
* the query will indicate that the class in question has no such annotation.
*
*
Note that this meta-annotation type has no effect if the annotated
* type is used to annotate anything other than a class. Note also
* that this meta-annotation only causes annotations to be inherited
* from superclasses; annotations on implemented interfaces have no
* effect.
*
*@authorJoshua Bloch
*@since1.5
* @jls 9.6.3.3 @Inherited*/@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)public @interfaceInherited {
}
注解的作用:
当某个注解类在它的类上定义了@Inherited注解,例如SpringBoot中的 @SpringBootApplication注解,@SpringBootApplication注解类就定义了@Inherited注解,看下源码中的红色部分:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters={
@Filter(type= FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type= FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })public @interfaceSpringBootApplication {
// .....省略}
那么现在有一个我们自己开发的类使用了这个注解,例如:
@SpringBootApplication
@Servicepublic classPerson {
}
然后有个类Employee继承了Person
public class Employee extendsPerson{
}
那么现在在判断Employee类上有没有@SpringBootApplication时,通过代码验证:
@Testpublic voidtest1(){
Class clazz= Employee.class;if(clazz.isAnnotationPresent(SpringBootApplication.class)){
System.out.println("true");
}
}
上面这个测试用例执行将输出true,也就是子类中能查找到@SpringBootApplication ,但同样,你用上述代码查找Employee类上是否有Spring的@Service注解时,会输出false,至此你应该明白@Inherited注解的用意了吧。
经过这样的分析,我们再来读一下JDK的文档,就会比较容易理解了,否则会觉的有些绕,下面列出 @interface注解的中文文档:
指示注释类型被自动继承。如果在注释类型声明中存在 Inherited 元注释,并且用户在某一类声明中查询该注释类型,同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。此过程会重复进行,直到找到此类型的注释或到达了该类层次结构的顶层 (Object) 为止。如果没有超类具有该类型的注释,则查询将指示当前类没有这样的注释。
注意,如果使用注释类型注释类以外的任何事物,此元注释类型都是无效的。还要注意,此元注释仅促成从超类继承注释;对已实现接口的注释无效。