AnnotationScanner添加scan方法,MethodAnnotationScanner扫描器添加对父类/父接口方法中具有相同签名方法的扫描支持

This commit is contained in:
huangchengxing 2022-06-30 15:28:36 +08:00
parent d1bba67d3a
commit 062ec707f2
6 changed files with 510 additions and 188 deletions

View File

@ -0,0 +1,276 @@
package cn.hutool.core.annotation.scanner;
import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Proxy;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
/**
* 为需要从类的层级结构中获取注解的{@link AnnotationScanner}提供基本实现
*
* @author huangchengxing
*/
public abstract class AbstractTypeAnnotationScanner<T extends AbstractTypeAnnotationScanner<T>> implements AnnotationScanner {
/**
* 是否允许扫描父类
*/
// FIXME rename includeSuperClass
private boolean includeSupperClass;
/**
* 是否允许扫描父接口
*/
private boolean includeInterfaces;
/**
* 过滤器若类型无法通过该过滤器则该类型及其树结构将直接不被查找
*/
private Predicate<Class<?>> filter;
/**
* 排除的类型以上类型及其树结构将直接不被查找
*/
private final Set<Class<?>> excludeTypes;
/**
* 转换器
*/
private final List<UnaryOperator<Class<?>>> converters;
/**
* 是否有转换器
*/
private boolean hasConverters;
/**
* 当前实例
*/
private final T typedThis;
/**
* 构造一个类注解扫描器
*
* @param includeSupperClass 是否允许扫描父类
* @param includeInterfaces 是否允许扫描父接口
* @param filter 过滤器
* @param excludeTypes 不包含的类型
*/
@SuppressWarnings("unchecked")
protected AbstractTypeAnnotationScanner(boolean includeSupperClass, boolean includeInterfaces, Predicate<Class<?>> filter, Set<Class<?>> excludeTypes) {
Assert.notNull(filter, "filter must not null");
Assert.notNull(excludeTypes, "excludeTypes must not null");
this.includeSupperClass = includeSupperClass;
this.includeInterfaces = includeInterfaces;
this.filter = filter;
this.excludeTypes = excludeTypes;
this.converters = new ArrayList<>();
this.typedThis = (T)this;
}
/**
* 是否允许扫描父类
*
* @return 是否允许扫描父类
*/
public boolean isIncludeSupperClass() {
return includeSupperClass;
}
/**
* 是否允许扫描父接口
*
* @return 是否允许扫描父接口
*/
public boolean isIncludeInterfaces() {
return includeInterfaces;
}
/**
* 设置过滤器若类型无法通过该过滤器则该类型及其树结构将直接不被查找
*
* @param filter 过滤器
* @return 当前实例
*/
public T setFilter(Predicate<Class<?>> filter) {
Assert.notNull(filter, "filter must not null");
this.filter = filter;
return typedThis;
}
/**
* 添加不扫描的类型该类型及其树结构将直接不被查找
*
* @param excludeTypes 不扫描的类型
* @return 当前实例
*/
public T addExcludeTypes(Class<?>... excludeTypes) {
CollUtil.addAll(this.excludeTypes, excludeTypes);
return typedThis;
}
/**
* 添加转换器
*
* @param converter 转换器
* @return 当前实例
* @see JdkProxyClassConverter
*/
public T addConverters(UnaryOperator<Class<?>> converter) {
Assert.notNull(converter, "converter must not null");
this.converters.add(converter);
if (!this.hasConverters) {
this.hasConverters = CollUtil.isNotEmpty(this.converters);
}
return typedThis;
}
/**
* 是否允许扫描父类
*
* @param includeSupperClass 是否
* @return 当前实例
*/
protected T setIncludeSupperClass(boolean includeSupperClass) {
this.includeSupperClass = includeSupperClass;
return typedThis;
}
/**
* 是否允许扫描父接口
*
* @param includeInterfaces 是否
* @return 当前实例
*/
protected T setIncludeInterfaces(boolean includeInterfaces) {
this.includeInterfaces = includeInterfaces;
return typedThis;
}
/**
* 则根据广度优先递归扫描类的层级结构并对层级结构中类/接口声明的层级索引和它们声明的注解对象进行处理
*
* @param consumer 对获取到的注解和注解对应的层级索引的处理
* @param annotatedElement 注解元素
* @param filter 注解过滤器无法通过过滤器的注解不会被处理该参数允许为空
*/
@Override
public void scan(BiConsumer<Integer, Annotation> consumer, AnnotatedElement annotatedElement, Predicate<Annotation> filter) {
filter = ObjectUtil.defaultIfNull(filter, annotation -> true);
final Class<?> sourceClass = getClassFormAnnotatedElement(annotatedElement);
final Deque<List<Class<?>>> classDeque = CollUtil.newLinkedList(CollUtil.newArrayList(sourceClass));
final Set<Class<?>> accessedTypes = new LinkedHashSet<>();
int index = 0;
while (!classDeque.isEmpty()) {
final List<Class<?>> currClassQueue = classDeque.removeFirst();
final List<Class<?>> nextClassQueue = new ArrayList<>();
for (Class<?> targetClass : currClassQueue) {
targetClass = convert(targetClass);
// 过滤不需要处理的类
if (isNotNeedProcess(accessedTypes, targetClass)) {
continue;
}
accessedTypes.add(targetClass);
// 扫描父类
scanSuperClassIfNecessary(nextClassQueue, targetClass);
// 扫描接口
scanInterfaceIfNecessary(nextClassQueue, targetClass);
// 处理层级索引和注解
final Annotation[] targetAnnotations = getAnnotationsFromTargetClass(annotatedElement, index, targetClass);
for (final Annotation annotation : targetAnnotations) {
if (AnnotationUtil.isNotJdkMateAnnotation(annotation.annotationType()) || filter.test(annotation)) {
consumer.accept(index, annotation);
}
}
index++;
}
if (CollUtil.isNotEmpty(nextClassQueue)) {
classDeque.addLast(nextClassQueue);
}
}
}
/**
* 从要搜索的注解元素上获得要递归的类型
*
* @param annotatedElement 注解元素
* @return 要递归的类型
*/
protected abstract Class<?> getClassFormAnnotatedElement(AnnotatedElement annotatedElement);
/**
* 从类上获取最终所需的目标注解
*
* @param source 最初的注解元素
* @param index 类的层级索引
* @param targetClass
* @return 最终所需的目标注解
*/
protected abstract Annotation[] getAnnotationsFromTargetClass(AnnotatedElement source, int index, Class<?> targetClass);
/**
* 当前类是否不需要处理
*/
protected boolean isNotNeedProcess(Set<Class<?>> accessedTypes, Class<?> targetClass) {
return ObjectUtil.isNull(targetClass)
|| accessedTypes.contains(targetClass)
|| excludeTypes.contains(targetClass)
|| filter.negate().test(targetClass);
}
/**
* {@link #includeInterfaces}{@code true}则将目标类的父接口也添加到nextClasses
*/
protected void scanInterfaceIfNecessary(List<Class<?>> nextClasses, Class<?> targetClass) {
if (includeInterfaces) {
final Class<?>[] interfaces = targetClass.getInterfaces();
if (ArrayUtil.isNotEmpty(interfaces)) {
CollUtil.addAll(nextClasses, interfaces);
}
}
}
/**
* {@link #includeSupperClass}{@code true}则将目标类的父类也添加到nextClasses
*/
protected void scanSuperClassIfNecessary(List<Class<?>> nextClassQueue, Class<?> targetClass) {
if (includeSupperClass) {
final Class<?> superClass = targetClass.getSuperclass();
if (!ObjectUtil.equals(superClass, Object.class) && ObjectUtil.isNotNull(superClass)) {
nextClassQueue.add(superClass);
}
}
}
/**
* 若存在转换器则使用转换器对目标类进行转换
*/
protected Class<?> convert(Class<?> target) {
if (hasConverters) {
for (UnaryOperator<Class<?>> converter : converters) {
target = converter.apply(target);
}
}
return target;
}
/**
* 若类型为jdk代理类则尝试转换为原始被代理类
*/
public static class JdkProxyClassConverter implements UnaryOperator<Class<?>> {
@Override
public Class<?> apply(Class<?> sourceClass) {
return Proxy.isProxyClass(sourceClass) ? apply(sourceClass.getSuperclass()) : sourceClass;
}
}
}

View File

@ -1,13 +1,17 @@
package cn.hutool.core.annotation.scanner;
import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -23,39 +27,73 @@ import java.util.stream.Stream;
public interface AnnotationScanner {
/**
* 是否支持扫描该注解元素
* 判断是否支持扫描该注解元素
*
* @param annotatedElement 注解元素
* @return 是否支持扫描该注解元素
* @param annotatedElement 注解元素
* @return 是否支持扫描该注解元素
*/
default boolean support(AnnotatedElement annotatedElement) {
return false;
}
/**
* 获取注解元素上的全部注解调用该方法前需要确保调用{@link #support(AnnotatedElement)}返回为true
* 获取注解元素上的全部注解调用该方法前需要确保调用{@link #support(AnnotatedElement)}返回为true
*
* @param annotatedElement 注解元素
* @return 元素上的注解
* @param annotatedElement 注解元素
* @return 注解
*/
List<Annotation> getAnnotations(AnnotatedElement annotatedElement);
default List<Annotation> getAnnotations(AnnotatedElement annotatedElement) {
final List<Annotation> annotations = new ArrayList<>();
scan((index, annotation) -> annotations.add(annotation), annotatedElement, null);
return annotations;
}
/**
* {@link #support(AnnotatedElement)}返回{@code true}
* 则调用并返回{@link #getAnnotations(AnnotatedElement)}结果
* 否则返回{@link Collections#emptyList()}
*
* @param annotatedElement 元素
* @return 元素上的注解
* @param annotatedElement 注解元素
* @return 注解
*/
default List<Annotation> getIfSupport(AnnotatedElement annotatedElement) {
return support(annotatedElement) ? getAnnotations(annotatedElement) : Collections.emptyList();
}
/**
* 扫描注解元素的层级结构若存在然后对获取到的注解和注解对应的层级索引进行处理
* 调用该方法前需要确保调用{@link #support(AnnotatedElement)}返回为true
*
* @param consumer 对获取到的注解和注解对应的层级索引的处理
* @param annotatedElement 注解元素
* @param filter 注解过滤器无法通过过滤器的注解不会被处理该参数允许为空
*/
default void scan(BiConsumer<Integer, Annotation> consumer, AnnotatedElement annotatedElement, Predicate<Annotation> filter) {
filter = ObjectUtil.defaultIfNull(filter, annotation -> true);
for (Annotation annotation : annotatedElement.getAnnotations()) {
if (AnnotationUtil.isNotJdkMateAnnotation(annotation.annotationType()) && filter.test(annotation)) {
consumer.accept(0, annotation);
}
}
}
/**
* {@link #support(AnnotatedElement)}返回{@code true}则调用{@link #scan(BiConsumer, AnnotatedElement, Predicate)}
*
* @param consumer 对获取到的注解和注解对应的层级索引的处理
* @param annotatedElement 注解元素
* @param filter 注解过滤器无法通过过滤器的注解不会被处理该参数允许为空
*/
default void scanIfSupport(BiConsumer<Integer, Annotation> consumer, AnnotatedElement annotatedElement, Predicate<Annotation> filter) {
if (support(annotatedElement)) {
scan(consumer, annotatedElement, filter);
}
}
/**
* 给定一组扫描器使用第一个支持处理该类型元素的扫描器获取元素上可能存在的注解
*
* @param annotatedElement 可注解元素
* @param annotatedElement 注解元素
* @param scanners 注解扫描器
* @return 注解
*/
@ -73,7 +111,7 @@ public interface AnnotationScanner {
/**
* 根据指定的扫描器扫描元素上可能存在的注解
*
* @param annotatedElement 注解元素
* @param annotatedElement 注解元素
* @param scanners 注解扫描器
* @return 注解
*/

View File

@ -1,11 +1,13 @@
package cn.hutool.core.annotation.scanner;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.util.ObjectUtil;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
/**
* 扫描{@link Field}上的注解
@ -14,14 +16,32 @@ import java.util.List;
*/
public class FieldAnnotationScanner implements AnnotationScanner {
/**
* 判断是否支持扫描该注解元素仅当注解元素是{@link Field}时返回{@code true}
*
* @param annotatedElement 注解元素
* @return 是否支持扫描该注解元素
*/
@Override
public boolean support(AnnotatedElement annotatedElement) {
return annotatedElement instanceof Field;
}
/**
* 扫描{@link Field}上直接声明的注解调用前需要确保调用{@link #support(AnnotatedElement)}返回为true
*
* @param consumer 对获取到的注解和注解对应的层级索引的处理
* @param annotatedElement 注解元素
* @param filter 注解过滤器无法通过过滤器的注解不会被处理该参数允许为空
*/
@Override
public List<Annotation> getAnnotations(AnnotatedElement annotatedElement) {
return CollUtil.newArrayList(annotatedElement.getAnnotations());
public void scan(BiConsumer<Integer, Annotation> consumer, AnnotatedElement annotatedElement, Predicate<Annotation> filter) {
filter = ObjectUtil.defaultIfNull(filter, annotation -> true);
for (Annotation annotation : annotatedElement.getAnnotations()) {
if (AnnotationUtil.isNotJdkMateAnnotation(annotation.annotationType()) && filter.test(annotation)) {
consumer.accept(0, annotation);
}
}
}
}

View File

@ -31,7 +31,7 @@ public class MetaAnnotationScanner implements AnnotationScanner {
private final boolean includeSupperMetaAnnotation;
/**
* 构造
* 构造一个元注解扫描器
*
* @param includeSupperMetaAnnotation 获取当前注解的元注解后是否继续递归扫描的元注解的元注解
*/
@ -46,30 +46,54 @@ public class MetaAnnotationScanner implements AnnotationScanner {
this(true);
}
/**
* 判断是否支持扫描该注解元素仅当注解元素是{@link Annotation}接口的子类{@link Class}时返回{@code true}
*
* @param annotatedElement 注解元素
* @return 是否支持扫描该注解元素
*/
@Override
public boolean support(AnnotatedElement annotatedElement) {
return (annotatedElement instanceof Class && ClassUtil.isAssignable(Annotation.class, (Class<?>) annotatedElement));
}
/**
* 获取注解元素上的全部注解调用该方法前需要确保调用{@link #support(AnnotatedElement)}返回为true
*
* @param annotatedElement 注解元素
* @return 注解
*/
@Override
public List<Annotation> getAnnotations(AnnotatedElement annotatedElement) {
final List<Annotation> annotations = new ArrayList<>();
scan(
(index, annotation) -> annotations.add(annotation),
annotatedElement,
annotation -> ObjectUtil.notEqual(annotation, annotatedElement)
);
return annotations;
}
/**
* 按广度优先扫描指定注解上的元注解对扫描到的注解与层级索引进行操作
*
* @param consumer 当前层级索引与操作
* @param source 源注解
* @param filter 过滤器
* @author huangchengxing
*/
public void scan(BiConsumer<Integer, Annotation> consumer, Class<? extends Annotation> source, Predicate<Annotation> filter) {
@SuppressWarnings("unchecked")
@Override
public void scan(BiConsumer<Integer, Annotation> consumer, AnnotatedElement source, Predicate<Annotation> filter) {
filter = ObjectUtil.defaultIfNull(filter, t -> true);
final Deque<List<Class<? extends Annotation>>> deque = CollUtil.newLinkedList(CollUtil.newArrayList(source));
final Deque<List<Class<? extends Annotation>>> deque = CollUtil.newLinkedList(CollUtil.newArrayList((Class<? extends Annotation>)source));
int distance = 0;
do {
final List<Class<? extends Annotation>> annotationTypes = deque.removeFirst();
for (final Class<? extends Annotation> type : annotationTypes) {
final List<Annotation> metaAnnotations = Stream.of(type.getAnnotations())
.filter(a -> !AnnotationUtil.isJdkMetaAnnotation(a.annotationType()))
.filter(filter)
.collect(Collectors.toList());
.filter(a -> !AnnotationUtil.isJdkMetaAnnotation(a.annotationType()))
.filter(filter)
.collect(Collectors.toList());
for (final Annotation metaAnnotation : metaAnnotations) {
consumer.accept(distance, metaAnnotation);
}
@ -79,16 +103,4 @@ public class MetaAnnotationScanner implements AnnotationScanner {
} while (includeSupperMetaAnnotation && !deque.isEmpty());
}
@SuppressWarnings("unchecked")
@Override
public List<Annotation> getAnnotations(AnnotatedElement annotatedElement) {
final List<Annotation> annotations = new ArrayList<>();
scan(
(index, annotation) -> annotations.add(annotation),
(Class<? extends Annotation>) annotatedElement,
annotation -> ObjectUtil.notEqual(annotation, annotatedElement)
);
return annotations;
}
}

View File

@ -1,27 +1,122 @@
package cn.hutool.core.annotation.scanner;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.StrUtil;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* 扫描{@link Method}上的注解
*
* @author huangchengxing
*/
public class MethodAnnotationScanner implements AnnotationScanner {
public class MethodAnnotationScanner extends AbstractTypeAnnotationScanner<MethodAnnotationScanner> implements AnnotationScanner {
/**
* 构造一个方法注解扫描器
*
* @param scanSameSignatureMethod 是否扫描类层级结构中具有相同方法签名的方法
* @param filter 过滤器
* @param excludeTypes 不包含的类型
*/
public MethodAnnotationScanner(boolean scanSameSignatureMethod, Predicate<Class<?>> filter, Set<Class<?>> excludeTypes) {
super(scanSameSignatureMethod, scanSameSignatureMethod, filter, excludeTypes);
}
/**
* 构造一个类注解扫描器
*
* @param scanSameSignatureMethod 是否扫描类层级结构中具有相同方法签名的方法
*/
public MethodAnnotationScanner(boolean scanSameSignatureMethod) {
this(scanSameSignatureMethod, targetClass -> true, CollUtil.newLinkedHashSet());
}
/**
* 构造一个类注解扫描器仅扫描该方法上直接声明的注解
*/
public MethodAnnotationScanner() {
this(false);
}
/**
* 判断是否支持扫描该注解元素仅当注解元素是{@link Method}时返回{@code true}
*
* @param annotatedElement 注解元素
* @return boolean 是否支持扫描该注解元素
*/
@Override
public boolean support(AnnotatedElement annotatedElement) {
return annotatedElement instanceof Method;
}
/**
* 获取声明该方法的类
*
* @param annotatedElement 注解元素
* @return java.lang.Class<?>
* @author huangchengxing
* @date 2022/6/29 17:21
* @see Method#getDeclaringClass()
*/
@Override
public List<Annotation> getAnnotations(AnnotatedElement annotatedElement) {
return CollUtil.newArrayList(annotatedElement.getAnnotations());
protected Class<?> getClassFormAnnotatedElement(AnnotatedElement annotatedElement) {
return ((Method)annotatedElement).getDeclaringClass();
}
/**
* 若父类/父接口中方法具有相同的方法签名则返回该方法上的注解
*
* @param source 原始方法
* @param index 类的层级索引
* @param targetClass
*/
@Override
protected Annotation[] getAnnotationsFromTargetClass(AnnotatedElement source, int index, Class<?> targetClass) {
Method sourceMethod = (Method) source;
return Stream.of(targetClass.getDeclaredMethods())
.filter(superMethod -> !superMethod.isBridge())
.filter(superMethod -> hasSameSignature(sourceMethod, superMethod))
.map(AnnotatedElement::getAnnotations)
.flatMap(Stream::of)
.toArray(Annotation[]::new);
}
/**
* 设置是否扫描类层级结构中具有相同方法签名的方法
*
* @param scanSuperMethodIfOverride 则是否扫描原方法
* @return 当前实例
*/
public MethodAnnotationScanner setScanSameSignatureMethod(boolean scanSuperMethodIfOverride) {
setIncludeInterfaces(scanSuperMethodIfOverride);
setIncludeSupperClass(scanSuperMethodIfOverride);
return this;
}
/**
* 该方法是否具备与扫描的方法相同的方法签名
*/
private boolean hasSameSignature(Method sourceMethod, Method superMethod) {
if (!StrUtil.equals(sourceMethod.getName(), superMethod.getName())) {
return false;
}
Class<?>[] sourceParameterTypes = sourceMethod.getParameterTypes();
Class<?>[] targetParameterTypes = superMethod.getParameterTypes();
if (sourceParameterTypes.length != targetParameterTypes.length) {
return false;
}
if (!ArrayUtil.containsAll(sourceParameterTypes, targetParameterTypes)) {
return false;
}
return ClassUtil.isAssignable(superMethod.getReturnType(), sourceMethod.getReturnType());
}
}

View File

@ -1,56 +1,20 @@
package cn.hutool.core.annotation.scanner;
import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Proxy;
import java.util.*;
import java.util.Set;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 扫描{@link Class}上的注解
*
* @author huangchengxing
*/
public class TypeAnnotationScanner implements AnnotationScanner {
/**
* 是否允许扫描父类
*/
private boolean includeSupperClass;
/**
* 是否允许扫描父接口
*/
private boolean includeInterfaces;
/**
* 过滤器若类型无法通过该过滤器则该类型及其树结构将直接不被查找
*/
private Predicate<Class<?>> filter;
/**
* 排除的类型以上类型及其树结构将直接不被查找
*/
private final Set<Class<?>> excludeTypes;
/**
* 转换器
*/
private final List<UnaryOperator<Class<?>>> converters;
/**
* 是否有转换器
*/
private boolean hasConverters;
public class TypeAnnotationScanner extends AbstractTypeAnnotationScanner<TypeAnnotationScanner> implements AnnotationScanner {
/**
* 构造一个类注解扫描器
@ -61,77 +25,49 @@ public class TypeAnnotationScanner implements AnnotationScanner {
* @param excludeTypes 不包含的类型
*/
public TypeAnnotationScanner(boolean includeSupperClass, boolean includeInterfaces, Predicate<Class<?>> filter, Set<Class<?>> excludeTypes) {
Assert.notNull(filter, "filter must not null");
Assert.notNull(excludeTypes, "excludeTypes must not null");
this.includeSupperClass = includeSupperClass;
this.includeInterfaces = includeInterfaces;
this.filter = filter;
this.excludeTypes = excludeTypes;
this.converters = new ArrayList<>();
super(includeSupperClass, includeInterfaces, filter, excludeTypes);
}
/**
* 构建一个类注解扫描器默认允许扫描指定元素的父类以及父接口
*/
public TypeAnnotationScanner() {
this(true, true, t -> true, CollUtil.newHashSet());
this(true, true, t -> true, CollUtil.newLinkedHashSet());
}
/**
* 是否允许扫描父类
* 判断是否支持扫描该注解元素仅当注解元素是{@link Class}接时返回{@code true}
*
* @return 是否允许扫描父类
* @param annotatedElement 注解元素
* @return 是否支持扫描该注解元素
*/
public boolean isIncludeSupperClass() {
return includeSupperClass;
@Override
public boolean support(AnnotatedElement annotatedElement) {
return annotatedElement instanceof Class;
}
/**
* 是否允许扫描父接口
* 将注解元素转为{@link Class}
*
* @return 是否允许扫描父接口
* @param annotatedElement 注解元素
* @return
*/
public boolean isIncludeInterfaces() {
return includeInterfaces;
@Override
protected Class<?> getClassFormAnnotatedElement(AnnotatedElement annotatedElement) {
return (Class<?>)annotatedElement;
}
/**
* 设置过滤器若类型无法通过该过滤器则该类型及其树结构将直接不被查找
* 获取{@link Class#getAnnotations()}
*
* @param filter 过滤器
* @return 当前实例
* @param source 最初的注解元素
* @param index 类的层级索引
* @param targetClass
* @return 类上直接声明的注解
*/
public TypeAnnotationScanner setFilter(Predicate<Class<?>> filter) {
Assert.notNull(filter, "filter must not null");
this.filter = filter;
return this;
}
/**
* 添加不扫描的类型该类型及其树结构将直接不被查找
*
* @param excludeTypes 不扫描的类型
* @return 当前实例
*/
public TypeAnnotationScanner addExcludeTypes(Class<?>... excludeTypes) {
CollUtil.addAll(this.excludeTypes, excludeTypes);
return this;
}
/**
* 添加转换器
*
* @param converter 转换器
* @return 当前实例
* @see JdkProxyClassConverter
*/
public TypeAnnotationScanner addConverters(UnaryOperator<Class<?>> converter) {
Assert.notNull(converter, "converter must not null");
this.converters.add(converter);
if (!this.hasConverters) {
this.hasConverters = true;
}
return this;
@Override
protected Annotation[] getAnnotationsFromTargetClass(AnnotatedElement source, int index, Class<?> targetClass) {
return targetClass.getAnnotations();
}
/**
@ -140,9 +76,9 @@ public class TypeAnnotationScanner implements AnnotationScanner {
* @param includeSupperClass 是否
* @return 当前实例
*/
@Override
public TypeAnnotationScanner setIncludeSupperClass(boolean includeSupperClass) {
this.includeSupperClass = includeSupperClass;
return this;
return super.setIncludeSupperClass(includeSupperClass);
}
/**
@ -151,75 +87,20 @@ public class TypeAnnotationScanner implements AnnotationScanner {
* @param includeInterfaces 是否
* @return 当前实例
*/
@Override
public TypeAnnotationScanner setIncludeInterfaces(boolean includeInterfaces) {
this.includeInterfaces = includeInterfaces;
return this;
}
@Override
public boolean support(AnnotatedElement annotatedElement) {
return annotatedElement instanceof Class;
}
@Override
public List<Annotation> getAnnotations(AnnotatedElement annotatedElement) {
return scan((Class<?>) annotatedElement).stream()
.map(Class::getAnnotations)
.flatMap(Stream::of)
.filter(a -> !AnnotationUtil.isJdkMetaAnnotation(a.annotationType()))
.collect(Collectors.toList());
}
private Class<?> convert(Class<?> target) {
if (hasConverters) {
converters.forEach(c -> c.apply(target));
}
return target;
}
/**
* 递归遍历当前类父类及其实现的父接口
*
* @param targetClass
*/
private Set<Class<?>> scan(Class<?> targetClass) {
Deque<Class<?>> classDeque = CollUtil.newLinkedList(targetClass);
Set<Class<?>> accessedTypes = new HashSet<>();
while (!classDeque.isEmpty()) {
Class<?> target = convert(classDeque.removeFirst());
// 若当前类已经访问过则无需再次处理
if (ObjectUtil.isNull(target) || accessedTypes.contains(target) || excludeTypes.contains(target) || filter.negate().test(target)) {
continue;
}
accessedTypes.add(target);
// 扫描父类
if (includeSupperClass) {
Class<?> superClass = target.getSuperclass();
if (!ObjectUtil.equals(superClass, Object.class) && ObjectUtil.isNotNull(superClass)) {
classDeque.addLast(superClass);
}
}
// 扫描接口
if (includeInterfaces) {
Class<?>[] interfaces = target.getInterfaces();
if (ArrayUtil.isNotEmpty(interfaces)) {
CollUtil.addAll(classDeque, interfaces);
}
}
}
return accessedTypes;
return super.setIncludeInterfaces(includeInterfaces);
}
/**
* 若类型为jdk代理类则尝试转换为原始被代理类
* @deprecated replace with {@link AbstractTypeAnnotationScanner.JdkProxyClassConverter}
*/
@Deprecated
public static class JdkProxyClassConverter implements UnaryOperator<Class<?>> {
@Override
public Class<?> apply(Class<?> sourceClass) {
return Proxy.isProxyClass(sourceClass) ? sourceClass.getSuperclass() : sourceClass;
return Proxy.isProxyClass(sourceClass) ? apply(sourceClass.getSuperclass()) : sourceClass;
}
}