All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hutool.core.annotation.scanner.MetaAnnotationScanner Maven / Gradle / Ivy

Go to download

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。

There is a newer version: 5.8.34
Show newest version
package cn.hutool.core.annotation.scanner;

import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ObjectUtil;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 扫描注解类上存在的注解,支持处理枚举实例或枚举类型
 * 需要注意,当待解析是枚举类时,有可能与{@link TypeAnnotationScanner}冲突
 *
 * @author huangchengxing
 * @see TypeAnnotationScanner
 */
public class MetaAnnotationScanner implements AnnotationScanner {

	/**
	 * 获取当前注解的元注解后,是否继续递归扫描的元注解的元注解
	 */
	private final boolean includeSupperMetaAnnotation;

	/**
	 * 构造一个元注解扫描器
	 *
	 * @param includeSupperMetaAnnotation 获取当前注解的元注解后,是否继续递归扫描的元注解的元注解
	 */
	public MetaAnnotationScanner(boolean includeSupperMetaAnnotation) {
		this.includeSupperMetaAnnotation = includeSupperMetaAnnotation;
	}

	/**
	 * 构造一个元注解扫描器,默认在扫描当前注解上的元注解后,并继续递归扫描元注解
	 */
	public MetaAnnotationScanner() {
		this(true);
	}

	/**
	 * 判断是否支持扫描该注解元素,仅当注解元素是{@link Annotation}接口的子类{@link Class}时返回{@code true}
	 *
	 * @param annotatedEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission
	 * @return 是否支持扫描该注解元素
	 */
	@Override
	public boolean support(AnnotatedElement annotatedEle) {
		return (annotatedEle instanceof Class && ClassUtil.isAssignable(Annotation.class, (Class) annotatedEle));
	}

	/**
	 * 获取注解元素上的全部注解。调用该方法前,需要确保调用{@link #support(AnnotatedElement)}返回为true
	 *
	 * @param annotatedEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission
	 * @return 注解
	 */
	@Override
	public List getAnnotations(AnnotatedElement annotatedEle) {
		final List annotations = new ArrayList<>();
		scan(
				(index, annotation) -> annotations.add(annotation), annotatedEle,
				annotation -> ObjectUtil.notEqual(annotation, annotatedEle)
		);
		return annotations;
	}

	/**
	 * 按广度优先扫描指定注解上的元注解,对扫描到的注解与层级索引进行操作
	 *
	 * @param consumer     当前层级索引与操作
	 * @param annotatedEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission
	 * @param filter       过滤器
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void scan(BiConsumer consumer, AnnotatedElement annotatedEle, Predicate filter) {
		filter = ObjectUtil.defaultIfNull(filter, a -> t -> true);
		Set> accessed = new HashSet<>();
		final Deque>> deque = CollUtil.newLinkedList(CollUtil.newArrayList((Class) annotatedEle));
		int distance = 0;
		do {
			final List> annotationTypes = deque.removeFirst();
			for (final Class type : annotationTypes) {
				final List metaAnnotations = Stream.of(type.getAnnotations())
						.filter(a -> !AnnotationUtil.isJdkMetaAnnotation(a.annotationType()))
						.filter(filter)
						.collect(Collectors.toList());
				for (final Annotation metaAnnotation : metaAnnotations) {
					consumer.accept(distance, metaAnnotation);
				}
				accessed.add(type);
				List> next = metaAnnotations.stream()
						.map(Annotation::annotationType)
						.filter(t -> !accessed.contains(t))
						.collect(Collectors.toList());
				if (CollUtil.isNotEmpty(next)) {
					deque.addLast(next);
				}
			}
			distance++;
		} while (includeSupperMetaAnnotation && !deque.isEmpty());
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy