何时用到了
//在创建AnnotatedGenericBeanDefinition对象的时候就用到了
public AnnotatedGenericBeanDefinition(Class<?> beanClass) {
setBeanClass(beanClass);
//使用AnnotationMetadata能够获取到类中的注解和指定
this.metadata = AnnotationMetadata.introspect(beanClass);//
}
一、AnnotationMetadata的作用
使用AnnotationMetadata能够操作类中的成员方法和注解,但是操作不了类中的属性
对方法的操作
//获取类中指定注解的所有方法
public static void test() {
//introspect():是入口
AnnotationMetadata introspect = AnnotationMetadata.introspect(AnnotationsScannerHandler.class);
//获取所有带有@Bean注解的方法
Set<MethodMetadata> methods = introspect.getAnnotatedMethods("org.springframework.context.annotation.Bean");
for (MethodMetadata method : methods) {
System.out.println(method.getMethodName());
}
}
public static void test() {
//introspect():是入口
AnnotationMetadata introspect = AnnotationMetadata.introspect(MergedAnnotationsEntity.class);
//判断当前类中是否有@Bean注解标注的方法
boolean b = introspect.hasAnnotatedMethods("org.springframework.context.annotation.Bean");
System.out.println(b);
}
对类上注解的操作
public static void test() {
AnnotationMetadata introspect = AnnotationMetadata.introspect(MergedAnnotationsEntity.class);
//获取类上注解的元注解,比如类上有@Service注解,此时就是获取@Service中元注解
Set<String> types = introspect.getMetaAnnotationTypes("org.springframework.stereotype.Service");
System.out.println(types);//打印出:[org.springframework.stereotype.Component, org.springframework.stereotype.Indexed]
}
public static void test() {
AnnotationMetadata introspect = AnnotationMetadata.introspect(MergedAnnotationsEntity.class);
//获取类上,指定注解的所有属性值,这里表示获取@Configuration注解的所有属性值,并返回一个map集合,其中属性的值value都是一个List集合
MultiValueMap<String, Object> value = introspect.getAllAnnotationAttributes("org.springframework.context.annotation.Configuration");
System.out.println(value);//打印出:{proxyBeanMethods=[true], value=[111111]}
}
public static void test() {
AnnotationMetadata introspect = AnnotationMetadata.introspect(MergedAnnotationsEntity.class);
//获取类上的所有注解全限定名
Set<String> types = introspect.getAnnotationTypes();
types.stream().forEach(v-> System.out.println(v));
}
public static void test() {
AnnotationMetadata introspect = AnnotationMetadata.introspect(MergedAnnotationsEntity.class);
//判断当前类中的注解是否有@Import注解信息,该方法操作的是注解中的注解
//@EnableConfigurationProperties注解,那么这里就是判断@EnableConfigurationProperties中是否包含@Import注解
boolean b = introspect.hasMetaAnnotation("org.springframework.context.annotation.Import");
System.out.println(b);//打印出true
}
public static void test() {
AnnotationMetadata introspect = AnnotationMetadata.introspect(MergedAnnotationsEntity.class);
//获取类上@Configuration注解的所有属性值
Map<String, Object> value =
introspect.getAnnotationAttributes("org.springframework.context.annotation.Configuration");
System.out.println(value);//打印出:{proxyBeanMethods=true, value=111111}
}
public static void test() {
AnnotationMetadata introspect = AnnotationMetadata.introspect(MergedAnnotationsEntity.class);
MergedAnnotations merage = introspect.getAnnotations();
//获取类上的@Configuration注解
MergedAnnotation<Configuration> configurationMergedAnnotation = merage.get(Configuration.class);
//并获取@Configuration的value属性值
String value = configurationMergedAnnotation.getString("value");
System.out.println(value);//打印出:111111
}
其他的功能
package org.springframework.core.type;
import org.springframework.lang.Nullable;
/**
* ClassMetadata:对Class的抽象和适配
*
* 此接口的所有方法,基本上都跟 Class 有关。
*/
public interface ClassMetadata {
// 获取className
String getClassName();
// 判断当前 是不是 接口
boolean isInterface();
//判断是否是注解
boolean isAnnotation();
// 判断是否是抽象
boolean isAbstract();
// 是否允许创建 不是接口且不是抽象类 这里就返回true了
default boolean isConcrete() {
return !(isInterface() || isAbstract());
}
// 判断 当前类是否 是 final
boolean isFinal();
// 是否是独立的(能够创建对象的) 比如是Class、或者内部类、静态内部类
boolean isIndependent();
// 如果当前类是内部类则返回 true
default boolean hasEnclosingClass() {
return (getEnclosingClassName() != null);
}
// 如果当前类为内部类,则获取外部类的全限定类名
@Nullable
String getEnclosingClassName();
// 基本都是true,只有当类型是 Object的时候才是false.. 也就是说 Object 不存在父类
default boolean hasSuperClass() {
return (getSuperClassName() != null);
}
// 获取父类的ClassName
@Nullable
String getSuperClassName();
// 会把实现的所有接口名称都返回
String[] getInterfaceNames();
// 返回类中定义的公共、私有、保护的内部类
String[] getMemberClassNames();
}
二、MergedAnnotations操作类上的注解
public static void test() {
//form()方法是入口
MergedAnnotations from = MergedAnnotations.from(MergedAnnotationsEntity.class);
//获取类上的@Configuration注解
MergedAnnotation<Configuration> configurationMergedAnnotation = from.get(Configuration.class);
//获取@Configuration注解中proxyBeanMethods属性的默认值
Optional<Object> proxyBeanMethods = configurationMergedAnnotation.getDefaultValue("proxyBeanMethods");
System.out.println("proxyBeanMethods的默认值:"+proxyBeanMethods.get());
Optional<Object> value = configurationMergedAnnotation.getDefaultValue("value");
System.out.println("value的默认值:"+value.get());
String value1 = configurationMergedAnnotation.getString("value");
System.out.println("value:的实际值:"+value1);
}
支持各种类型值的获取
三、AnnotationAttributes
他的作用就是对AnnotationMetadata的结果进行一层封装,让我们能够以更好的方式获取注解里面的属性值
public static void test() {
//先获取类的原信息对象
AnnotationMetadata introspect = AnnotationMetadata.introspect(AnnotationsScannerHandler.class);
//获取类上的@ComponentScan注解信息
//看到这里返回的是一个map集合,泛型是Object类型的,那么获取value值就要强制类型转化
Map<String, Object> annotationAttributes = introspect.getAnnotationAttributes(ComponentScan.class.getName());
//但是使用AnnotationAttributes讲map封装一下就不需要做强制类型转换了,因为在他的内部做了转换
AnnotationAttributes attributes = AnnotationAttributes.fromMap(annotationAttributes);
String string = attributes.getString("resourcePattern");
String[] stringArray = attributes.getStringArray("value");
String[] basePackages = attributes.getStringArray("basePackages");
boolean aBoolean = attributes.getBoolean("useDefaultFilters");
Class<?>[] classArray = attributes.getClassArray("basePackageClasses");
Object orDefault = attributes.getOrDefault("resourcePattern","给个默认值");
System.out.println(string);
System.out.println(stringArray.length);
System.out.println(basePackages.length);
System.out.println(aBoolean);
System.out.println(classArray);
System.out.println(orDefault);
}
【打印出结果】
**/*.class
0
0
true
[Ljava.lang.Class;@76707e36
**/*.class