【源码】Spring —— TypeFilter 解读
前言版本TypeFilterAbstractTypeHierarchyTraversingFilterAssignableTypeFilterAnnotationTypeFilter
demo总结
前言
在 ClassPathBeanDefinitionScanner 类中,其从父类 ClassPathScanningCandidateComponentProvider 获取需要注册的备选 BeanDefinition 时,会使用 includeFilters 和 excludeFilters 对扫描路径下的类进行 匹配过滤
private final List
<TypeFilter> includeFilters
= new LinkedList<>();
private final List
<TypeFilter> excludeFilters
= new LinkedList<>();
本章节介绍 TypeFilter
版本
Spring 5.2.x
TypeFilter
@FunctionalInterface
public interface TypeFilter {
boolean match(MetadataReader metadataReader
, MetadataReaderFactory metadataReaderFactory
)
throws IOException
;
}
函数式接口,不难推测应该是以 MetadataReader 中解析的 ClassMetadata 和 AnnotationMetadata 进行匹配
关于 ClassMetadata 和 AnnotationMetadata,可以阅读下面文章
【源码】Spring —— ClassMetadata AnnotatedTypeMetadata 解读
AbstractTypeHierarchyTraversingFilter
public abstract class AbstractTypeHierarchyTraversingFilter implements TypeFilter {
protected final Log logger
= LogFactory
.getLog(getClass());
private final boolean considerInherited
;
private final boolean considerInterfaces
;
protected AbstractTypeHierarchyTraversingFilter(boolean considerInherited
, boolean considerInterfaces
) {
this.considerInherited
= considerInherited
;
this.considerInterfaces
= considerInterfaces
;
}
@Override
public boolean match(MetadataReader metadataReader
, MetadataReaderFactory metadataReaderFactory
)
throws IOException
{
if (matchSelf(metadataReader
)) {
return true;
}
ClassMetadata metadata
= metadataReader
.getClassMetadata();
if (matchClassName(metadata
.getClassName())) {
return true;
}
if (this.considerInherited
) {
String superClassName
= metadata
.getSuperClassName();
if (superClassName
!= null
) {
Boolean superClassMatch
= matchSuperClass(superClassName
);
if (superClassMatch
!= null
) {
if (superClassMatch
.booleanValue()) {
return true;
}
}
else {
try {
if (match(metadata
.getSuperClassName(), metadataReaderFactory
)) {
return true;
}
}
catch (IOException ex
) {
if (logger
.isDebugEnabled()) {
logger
.debug("Could not read super class [" + metadata
.getSuperClassName() +
"] of type-filtered class [" + metadata
.getClassName() + "]");
}
}
}
}
}
if (this.considerInterfaces
) {
for (String ifc
: metadata
.getInterfaceNames()) {
Boolean interfaceMatch
= matchInterface(ifc
);
if (interfaceMatch
!= null
) {
if (interfaceMatch
.booleanValue()) {
return true;
}
}
else {
try {
if (match(ifc
, metadataReaderFactory
)) {
return true;
}
}
catch (IOException ex
) {
if (logger
.isDebugEnabled()) {
logger
.debug("Could not read interface [" + ifc
+ "] for type-filtered class [" +
metadata
.getClassName() + "]");
}
}
}
}
}
return false;
}
}
AbstractTypeHierarchyTraversingFilter,抽象方法,定义了 match 方法的模板,具体实现都交给子类实现
AssignableTypeFilter
public class AssignableTypeFilter extends AbstractTypeHierarchyTraversingFilter {
private final Class
<?> targetType
;
public AssignableTypeFilter(Class
<?> targetType
) {
super(true, true);
this.targetType
= targetType
;
}
public final Class
<?> getTargetType() {
return this.targetType
;
}
@Override
protected boolean matchClassName(String className
) {
return this.targetType
.getName().equals(className
);
}
@Override
@Nullable
protected Boolean
matchSuperClass(String superClassName
) {
return matchTargetType(superClassName
);
}
@Override
@Nullable
protected Boolean
matchInterface(String interfaceName
) {
return matchTargetType(interfaceName
);
}
@Nullable
protected Boolean
matchTargetType(String typeName
) {
if (this.targetType
.getName().equals(typeName
)) {
return true;
}
else if (Object
.class.getName().equals(typeName
)) {
return false;
}
else if (typeName
.startsWith("java")) {
try {
Class
<?> clazz
= ClassUtils
.forName(typeName
, getClass().getClassLoader());
return this.targetType
.isAssignableFrom(clazz
);
}
catch (Throwable ex
) {
}
}
return null
;
}
}
基于 Class 类型的匹配,考虑 父类 和 接口,实现了抽象父类定义的匹配方法,匹配细节见注释
AnnotationTypeFilter
public class AnnotationTypeFilter extends AbstractTypeHierarchyTraversingFilter {
private final Class
<? extends Annotation> annotationType
;
private final boolean considerMetaAnnotations
;
public AnnotationTypeFilter(Class
<? extends Annotation> annotationType
) {
this(annotationType
, true, false);
}
public AnnotationTypeFilter(Class
<? extends Annotation> annotationType
, boolean considerMetaAnnotations
) {
this(annotationType
, considerMetaAnnotations
, false);
}
public AnnotationTypeFilter(
Class
<? extends Annotation> annotationType
, boolean considerMetaAnnotations
, boolean considerInterfaces
) {
super(annotationType
.isAnnotationPresent(Inherited
.class), considerInterfaces
);
this.annotationType
= annotationType
;
this.considerMetaAnnotations
= considerMetaAnnotations
;
}
public final Class
<? extends Annotation> getAnnotationType() {
return this.annotationType
;
}
@Override
protected boolean matchSelf(MetadataReader metadataReader
) {
AnnotationMetadata metadata
= metadataReader
.getAnnotationMetadata();
return metadata
.hasAnnotation(this.annotationType
.getName()) ||
(this.considerMetaAnnotations
&& metadata
.hasMetaAnnotation(this.annotationType
.getName()));
}
@Override
@Nullable
protected Boolean
matchSuperClass(String superClassName
) {
return hasAnnotation(superClassName
);
}
@Override
@Nullable
protected Boolean
matchInterface(String interfaceName
) {
return hasAnnotation(interfaceName
);
}
@Nullable
protected Boolean
hasAnnotation(String typeName
) {
if (Object
.class.getName().equals(typeName
)) {
return false;
}
else if (typeName
.startsWith("java")) {
if (!this.annotationType
.getName().startsWith("java")) {
return false;
}
try {
Class
<?> clazz
= ClassUtils
.forName(typeName
, getClass().getClassLoader());
return ((this.considerMetaAnnotations
? AnnotationUtils
.getAnnotation(clazz
, this.annotationType
) :
clazz
.getAnnotation(this.annotationType
)) != null
);
}
catch (Throwable ex
) {
}
}
return null
;
}
}
基于 Annotation 类型的匹配,匹配细节见注释
demo
public void test() throws IOException
{
TypeFilter classTypeFilter
=
new AssignableTypeFilter(A
.class);
TypeFilter annotationTypeFilter
=
new AnnotationTypeFilter(Component
.class);
MetadataReaderFactory metadataReaderFactory
= new SimpleMetadataReaderFactory();
MetadataReader metadataReader
= metadataReaderFactory
.getMetadataReader("com.xsn.convert.TestTypeFilter.B");
System
.out
.println(classTypeFilter
.match(metadataReader
, metadataReaderFactory
));
System
.out
.println(annotationTypeFilter
.match(metadataReader
, metadataReaderFactory
));
}
结果:
true
true
总结
很简单的一个类,主要基于 Class Annotation 等规则 匹配过滤 目标类型