Spring注解编程基石(三)

目录

 

AnnotationUtils 源码分析

方法列表

方法源码

AnnotatedElementUtils 源码分析


Spring注解编程基石(一)

Spring注解编程基石(二)

Spring注解编程基石(三)

Spring注解编程基石(四)


AnnotationUtils 源码分析

方法列表

//从指定annotation 上查找单个指定annotationType的注解。返回值为它本身或者直接元注解。
public static  A getAnnotation(Annotation annotation, Class annotationType);
//从指定annotatedElement 上查找单个指定annotationType的注解。返回值为应用在annotatedElement上的注解或者注解的第一级元注解。
public static  A getAnnotation(AnnotatedElement annotatedElement, Class annotationType);
//从指定method 上查找单个指定annotationType的注解。返回值为应用在method上的注解或者注解的第一级元注解。
public static  A getAnnotation(Method method, Class annotationType);

//从指定class 上查找单个指定annotationType的注解。查找遍历它的注解,实现接口,superclass。
public static  A findAnnotation(Class clazz, @Nullable Class annotationType);
//从指定annotatedElement 上查找单个指定annotationType的注解。返回值为应用在annotatedElement上的注解或者元注解。
public static  A findAnnotation(AnnotatedElement annotatedElement, @Nullable Class annotationType); 
//从指定method 上查找单个指定annotationType的注解。返回值为应用在method上的注解或者超类(或者接口)上的overrided的方法的注解。
public static  A findAnnotation(Method method, @Nullable Class annotationType);

get***方法源码

    
	public static  A getAnnotation(AnnotatedElement annotatedElement, Class annotationType) {
		// 如果是java包下注解获取声明的注解。
		if (AnnotationFilter.PLAIN.matches(annotationType) ||
				AnnotationsScanner.hasPlainJavaAnnotationsOnly(annotatedElement)) {
			return annotatedElement.getAnnotation(annotationType);
		}
		// Exhaustive retrieval of merged annotations...
		return MergedAnnotations.from(annotatedElement, SearchStrategy.INHERITED_ANNOTATIONS, RepeatableContainers.none())
				.get(annotationType).withNonMergedAttributes()
				.synthesize(AnnotationUtils::isSingleLevelPresent).orElse(null);
	}
    
	public static  A getAnnotation(Annotation annotation, Class annotationType) {
		// Shortcut: directly present on the element, with no merging needed?
		if (annotationType.isInstance(annotation)) {
			return synthesizeAnnotation((A) annotation, annotationType);
		}
		// Shortcut: no searchable annotations to be found on plain Java classes and core Spring types...
		if (AnnotationsScanner.hasPlainJavaAnnotationsOnly(annotation)) {
			return null;
		}
		// Exhaustive retrieval of merged annotations...
		return MergedAnnotations.from(annotation, new Annotation[] {annotation}, RepeatableContainers.none())
				.get(annotationType).withNonMergedAttributes()
				.synthesize(AnnotationUtils::isSingleLevelPresent).orElse(null);
	}    
    
	public static  A getAnnotation(Method method, Class annotationType) {
		Method resolvedMethod = BridgeMethodResolver.findBridgedMethod(method);
		return getAnnotation((AnnotatedElement) resolvedMethod, annotationType);
	}

find***方法源码

	public static  A findAnnotation(Class clazz, @Nullable Class annotationType) {
		if (annotationType == null) {
			return null;
		}
		// Shortcut: directly present on the element, with no merging needed?
		if (AnnotationFilter.PLAIN.matches(annotationType) ||
				AnnotationsScanner.hasPlainJavaAnnotationsOnly(clazz)) {
			return clazz.getDeclaredAnnotation(annotationType);
		}
		// Exhaustive retrieval of merged annotations...
		return MergedAnnotations.from(clazz, SearchStrategy.TYPE_HIERARCHY, RepeatableContainers.none())
				.get(annotationType).withNonMergedAttributes()
				.synthesize(MergedAnnotation::isPresent).orElse(null);
	}
    
	public static  A findAnnotation(Method method, @Nullable Class annotationType) {
		if (annotationType == null) {
			return null;
		}
		// Shortcut: directly present on the element, with no merging needed?
		if (AnnotationFilter.PLAIN.matches(annotationType) ||
				AnnotationsScanner.hasPlainJavaAnnotationsOnly(method)) {
			return method.getDeclaredAnnotation(annotationType);
		}
		// Exhaustive retrieval of merged annotations...
		return MergedAnnotations.from(method, SearchStrategy.TYPE_HIERARCHY, RepeatableContainers.none())
				.get(annotationType).withNonMergedAttributes()
				.synthesize(MergedAnnotation::isPresent).orElse(null);
	}
    
 
	public static  A findAnnotation(
			AnnotatedElement annotatedElement, @Nullable Class annotationType) {

		if (annotationType == null) {
			return null;
		}
		// Shortcut: directly present on the element, with no merging needed?
		if (AnnotationFilter.PLAIN.matches(annotationType) ||
				AnnotationsScanner.hasPlainJavaAnnotationsOnly(annotatedElement)) {
			return annotatedElement.getDeclaredAnnotation(annotationType);
		}
		// Exhaustive retrieval of merged annotations...
		return MergedAnnotations.from(annotatedElement, SearchStrategy.INHERITED_ANNOTATIONS, RepeatableContainers.none())
				.get(annotationType).withNonMergedAttributes()
				.synthesize(MergedAnnotation::isPresent).orElse(null);
	}
 

AnnotatedElementUtils 源码分析

synthesizeAnnotation

synthesizeAnnotation,合成Annotation,通过获取一个动态代理注解(相当于调用者传进来的注解会被代理掉)来访问Annotation,该方法是别名注解@AliasFor的核心原理。

    final class TypeMappedAnnotation extends AbstractMergedAnnotation {
            protected A createSynthesized() {
            return SynthesizedMergedAnnotationInvocationHandler.createProxy(this, getType());
        }
    }


	static  A createProxy(MergedAnnotation annotation, Class type) {
		ClassLoader classLoader = type.getClassLoader();
		InvocationHandler handler = new SynthesizedMergedAnnotationInvocationHandler<>(annotation, type);
		Class[] interfaces = isVisible(classLoader, SynthesizedAnnotation.class) ?
				new Class[] {type, SynthesizedAnnotation.class} : new Class[] {type};
		return (A) Proxy.newProxyInstance(classLoader, interfaces, handler);
	}
final class SynthesizedMergedAnnotationInvocationHandler implements InvocationHandler {

    //Annotation
	private final MergedAnnotation annotation;
    annotation的类型
	private final Class type;
    属性方法
	private final AttributeMethods attributes;

	@Nullable
	private volatile Integer hashCode;


	private SynthesizedMergedAnnotationInvocationHandler(MergedAnnotation annotation, Class type) {
		Assert.notNull(annotation, "MergedAnnotation must not be null");
		Assert.notNull(type, "Type must not be null");
		Assert.isTrue(type.isAnnotation(), "Type must be an annotation");
		this.annotation = annotation;
		this.type = type;
		this.attributes = AttributeMethods.forAnnotationType(type);
		for (int i = 0; i < this.attributes.size(); i++) {
			getAttributeValue(this.attributes.get(i));
		}
	}


	@Override
	public Object invoke(Object proxy, Method method, Object[] args) {
		if (ReflectionUtils.isEqualsMethod(method)) {
			return annotationEquals(args[0]);
		}
		if (ReflectionUtils.isHashCodeMethod(method)) {
			return annotationHashCode();
		}
		if (ReflectionUtils.isToStringMethod(method)) {
			return this.annotation.toString();
		}
		if (isAnnotationTypeMethod(method)) {
			return this.type;
		}
		if (this.attributes.indexOf(method.getName()) != -1) {
			return getAttributeValue(method);
		}
		throw new AnnotationConfigurationException(String.format(
				"Method [%s] is unsupported for synthesized annotation type [%s]", method, this.type));
	}


	private Object getAttributeValue(Method method) {
		String name = method.getName();
		Class type = ClassUtils.resolvePrimitiveIfNecessary(method.getReturnType());
		return this.annotation.getValue(name, type).orElseThrow(
				() -> new NoSuchElementException("No value found for attribute named '" + name +
						"' in merged annotation " + this.annotation.getType().getName()));
	}

四中示例:

生成的TypeMappedAnnotation实例为:

@demon.study.A_C(c1=this is root, c2=this is root, c3=A_C_3, c4=A_C_4, c5=A_C_4, c6=A_C_6)

这是一个不存在的注解,因此生成一个代理类表示此注解。

 

你可能感兴趣的:(#,Spring)