spring-core提供的AnnotationUtils工具功能很强大,也很灵活,其中的synthesizeAnnotation方法我一起没搞明白它的使用场景,直到今天我的工作用上了它,学会它的使用。
synthesizeAnnotation方法说明:
通过将包含了注解字段值的Map封装在动态代理(dynamic proxy)中,从Map提供的注释属性合成注释对象(Annotation),该动态代理实现指定注释类型的注释,并透明地强制使用@AliasFor注释的注释属性的属性别名语义。
对于没有默认值的注解属性,Map必须包含在提供的annotationType中定义的每个属性的键值对。嵌套映射和映射的嵌套数组将分别递归合成为嵌套注释或注释的嵌套数组。
请注意,AnnotationAttributes是一种特殊类型的Map,是该方法的属性参数的理想候选。
public static <A extends Annotation> A synthesizeAnnotation(Map<String, Object> attributes,
Class<A> annotationType, @Nullable AnnotatedElement annotatedElement);
synthesize的意思是合成,synthesizeAnnotation就是合成注解
就是根据Map对象定义的指定注解的字段的值 ,创建一个注解对象。调用非常简单,使用示例:
import static org.junit.Assert.*;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.springframework.core.annotation.AliasFor;
import org.springframework.core.annotation.AnnotationUtils;
public class SpringAnnotationUtilsTest {
@Test
public void testSynthesizeAnnotation() {
try {
Map<String, Object> attrs = new HashMap<>();
String[] basePackages = new String[] {"net.gdface.bean","gu.simplemq"};
// 将注解的字段值加入Map
attrs.put("basePackages", basePackages);
/**
* 调用 synthesizeAnnotation 创建 @CasbanScan 注解对象
* 这里 synthesizeAnnotation 方法的 annotatedElement 参数可以填null
**/
CasbanScan annot = AnnotationUtils.synthesizeAnnotation(attrs, CasbanScan.class, null);
System.out.println(annot);
assertArrayEquals(basePackages, annot.basePackages());
assertArrayEquals(basePackages, annot.value());
} catch (Throwable e) {
e.printStackTrace();
fail();
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CasbanScan {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
}
}
有了注解合成功能,其实可以把注解当做一个只读的数据对象使用,用于参数传递也是很方便,有时就省去了定义多余的数据结构的工作。