介绍
直接看下面这篇博客就行:
【小家Spring】聊聊Spring中的那些【Metadata】,举例讲解:AnnotationMetadata、 MethodMetadata
使用
干看原理可能会有些深奥,这里对ClassMetadata及实现类StandardClassMetadata,以及AnnotationMetadata及实现类StandardAnnotationMetadata进行一些代码上的使用,帮助理解:
@Configuration("MetaDataDemoConfiguration")
public class MetaDataDemo {
@Autowired
private String test1() {
return "MetaDataDemo";
}
@Bean
public String test2() {
return "MetaDataDemo";
}
}
public static void main(String[] args) {
System.out.println("------------------------ClassMetadata--------------------------");
ClassMetadata classMetadata = new StandardClassMetadata(MetaDataDemo.class);
System.out.println(classMetadata.getClassName()); //com.test.MetaDataDemo
System.out.println(classMetadata.hasSuperClass()); //true:除了Object以外应该都是true
System.out.println(classMetadata.isAnnotation()); //false:该类本身并不是一个注解
System.out.println("------------------------AnnotationMetadata--------------------------");
AnnotationMetadata annotationMetadata = new StandardAnnotationMetadata(MetaDataDemo.class);
System.out.println(annotationMetadata.getAnnotationTypes()); //[org.springframework.context.annotation.Configuration]
System.out.println(annotationMetadata.getMetaAnnotationTypes(Configuration.class.getName())); //[org.springframework.stereotype.Component]
System.out.println(annotationMetadata.isAnnotated( Configuration.class.getName())); //true:注意这里与上面ClassMetadata.isAnnotation()的不同!
System.out.println(annotationMetadata.hasAnnotation(Configuration.class.getName())); //true,hasAnnotation()和上一行的isAnnotated()应该是一样的。
System.out.println(annotationMetadata.hasAnnotation(Controller.class.getName())); //false
System.out.println(annotationMetadata.hasMetaAnnotation(Configuration.class.getName())); //false:注意,MetaAnnotation是Component而不是Configuraion
annotationMetadata.getAnnotatedMethods(Autowired.class.getName()).forEach(methodMetadata -> {
System.out.println(methodMetadata.getClass()); // class org.springframework.core.type.StandardMethodMetadata
System.out.println(methodMetadata.getMethodName()); // test1 & test2
System.out.println(methodMetadata.getReturnTypeName()); // java.lang.String
});
}
而对于MethodMetadata,传入的参数不是class而是反射的method:
System.out.println("------------------------MethodMetadata--------------------------");
Method method1 = null;
try {
Class cl = Class.forName("com.test.MetaDataDemo");
method1 = cl.getDeclaredMethod("test1");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
if(method1 != null){
MethodMetadata methodMetadata = new StandardMethodMetadata(method1);
System.out.println(methodMetadata.getMethodName()); //test1
System.out.println(methodMetadata.getReturnTypeName()); //java.lang.String
System.out.println(methodMetadata.isOverridable()); //false
}
注:
AnnotationMetadata和AnnotatedElement
AnnotationMetadata在spring中最常用的是metadata.isAnnotated(XXX.class.getName());
可以通过这个来判断类或方法是否被@XXX注解所标记
而AnnotationElement中最常用的
Configuration configuration = AnnotatedElementUtils.findMergedAnnotation(element, XXX.class);
方法,
不仅可以用于判断类或方法是否含有@XXX注解,还可以获取整个注解的各种属性值。
例如我们以属性值较多的@RequestMapping为例:
@RequestMapping(value = {"test1Value","test2Value"},params = "testParam",headers = "testHeader")
public class AnnotatedElementMemo {
}
System.out.println("------------------------AnnotationElement--------------------------");
RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(AnnotatedElementMemo.class, RequestMapping.class);
System.out.println(Arrays.toString(requestMapping.value())); //[test1Value, test2Value]
System.out.println(Arrays.toString(requestMapping.headers())); //[testHeader]
System.out.println(Arrays.toString(requestMapping.params())); //[testParam]