import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
import java.io.IOException;
import java.util.Set;
ClassPathScanningCandidateComponentProvider classScanner = new ClassPathScanningCandidateComponentProvider(false);
// 添加“包含”类型的过滤器
classScanner.addIncludeFilter(new TypeFilter() {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
// 包含具体类,即排除interface和abstract
return metadataReader.getClassMetadata().isConcrete();
}
});
// 添加“排除”类型的过滤器
classScanner.addExcludeFilter(new TypeFilter() {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
// 排除嵌套类,即仅为顶级类
return metadataReader.getClassMetadata().hasEnclosingClass();
}
});
// 扫描类路径
Set<BeanDefinition> beanDefinitions = classScanner.findCandidateComponents("com.example.demo");
for (BeanDefinition beanDefinition : beanDefinitions) {
// 通过className查找Class对象
Class<?> aClass = Class.forName(beanDefinition.getBeanClassName());
}
- 构造函数
new ClassPathScanningCandidateComponentProvider(false)
中false
表示不使用默认过滤器; addIncludeFilter(TypeFilter includeFilter)
至少需要1
个否则无法扫描,addExcludeFilter(TypeFilter excludeFilter)
根据需要添加(可不用);- 可以使用
1
个classScanner.addIncludeFilter(new TypeFilter() {})
表达全部的包含和排除条件,例如:
classScanner.addIncludeFilter(new TypeFilter() {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
// 匹配顶级类,即排除interface、abstract、嵌套类
return !metadataReader.getClassMetadata().hasEnclosingClass();
}
});
classScanner.addIncludeFilter(new TypeFilter() {})
可以使用lambda
表达式,例如:
classScanner.addIncludeFilter((metadataReader, metadataReaderFactory) -> !metadataReader.getClassMetadata().hasEnclosingClass());
(完)