spring 源码系列(二) 元数据metadata

介绍

直接看下面这篇博客就行:
【小家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]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值