spring中组合注解随处可见,比如springboot的主类上的注解@SpringBootApplication里就包含多个注解,如下图所示

而且这些注解里又包含其他注解,我们知道原生java是不支持直接获取当前类的所实现的注解的注解的,就是说,我们用注解@A标记了注解@B,然后又用@B标记了某个类或者方法,通过反射这个类,是无法知道该类或者方法被@A标记的。那么springboot底层是如何实现的呢?接下来模拟实现过程。
import java.lang.annotation.*;
/**
* 自己构建注解A
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface A {
}
import java.lang.annotation.*;
/**
* 构建注解B,并用@A标记
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@A
public @interface B {
}
/**
* 建立一个类,用@B标记
*/
@B
public class MyClass {
}
接下来我们通过递归的方式验证MyClass是否被@A标记
import javax.annotation.*;
import java.lang.annotation.*;
public class Demo {
public static void main(String[] args) {
getAnnos(MyClass.class);
}
private static void getAnnos(Class<?> classz) {
Annotation[] annotations;
annotations = classz.getAnnotations();
for (Annotation annotation : annotations) {
//原生注解中存在循环,为防止内存溢出,将这些注解排除
if (annotation.annotationType() != Deprecated.class &&
annotation.annotationType() != SuppressWarnings.class &&
annotation.annotationType() != Override.class &&
annotation.annotationType() != PostConstruct.class &&
annotation.annotationType() != PreDestroy.class &&
annotation.annotationType() != Resource.class &&
annotation.annotationType() != Resources.class &&
annotation.annotationType() != Generated.class &&
annotation.annotationType() != Target.class &&
annotation.annotationType() != Retention.class &&
annotation.annotationType() != Documented.class &&
annotation.annotationType() != Inherited.class
) {
if (annotation.annotationType() == A.class) {
System.out.println(" 存在注解 @A ");
} else {
getAnnos(annotation.annotationType());
}
}
}
}
}
运行结果如下

这样就找到了MyClass中的注解@A了。
本文探讨了Java中SpringBoot如何处理组合注解的场景,例如@SpringBootApplication。由于原生Java不支持直接获取注解的注解,文章解释了SpringBoot通过递归方式检测类是否被特定注解标记,以此实现对组合注解的识别。
1635

被折叠的 条评论
为什么被折叠?



