组合注解与元注解

概念

  • 元注解: 可以注解到别的注解上的注解;
  • 组合注解:被注解的注解;

组合注解好处

  1. 简单化注解配置,一个组合注解可以代表多个有特定属性值的元注解;
  2. 提供了很好的扩展性,可以根据实际需要灵活的自定义注解。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Meta1 {
    String name() default "Meta1";
    int age() default 28;
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Meta2 {
    String sex();
}
//纯简化配置
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Meta1(name="langxie", age=27)
@Meta2(sex="male")
public @interface Sub {

}
//简化配置+灵活扩展
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Meta1(name="langxie", age=27)
@Meta2(sex="male")
public @interface Sub {
    String phone();  //扩展属性
}

组合注解的解析

  1. 从当前类或方法等处获取注解;
  2. 获得该注解的class对象;
  3. 继续递归获取该class对象或方法中的注解;

Spring提供了AnnotationUtils可以对组合注解进行解析,主要逻辑如下:

private static <A extends Annotation> A findAnnotation(Class> clazz, Class<A> annotationType, Set<Annotation> visited) {
        try {
            A annotation = clazz.getDeclaredAnnotation(annotationType);
            if (annotation != null) {
                return annotation;
            }
            for (Annotation declaredAnn : clazz.getDeclaredAnnotations()) {
                Classextends Annotation> declaredType = declaredAnn.annotationType();
                if (!isInJavaLangAnnotationPackage(declaredType) && visited.add(declaredAnn)) {
                    annotation = findAnnotation(declaredType, annotationType, visited);
                    if (annotation != null) {
                        return annotation;
                    }
                }
            }
        }
        catch (Throwable ex) {
            handleIntrospectionFailure(clazz, ex);
            return null;
        }

        for (Class ifc : clazz.getInterfaces()) {
            A annotation = findAnnotation(ifc, annotationType, visited);
            if (annotation != null) {
                return annotation;
            }
        }

        Class superclass = clazz.getSuperclass();
        if (superclass == null || Object.class == superclass) {
            return null;
        }
        return findAnnotation(superclass, annotationType, visited);
    }

你可能感兴趣的:(Spring-Boot)