首页 > 代码库 > Spring根据包名获取包路径下的所有类

Spring根据包名获取包路径下的所有类

参考mybatis MapperScannerConfigurer.java

技术分享

 

最终找到 Spring的一个类  ClassPathBeanDefinitionScanner.java

参考ClassPathBeanDefinitionScanner 和它的父类 ClassPathScanningCandidateComponentProvider,将一些代码进行抽取,得到如下工具类。

import org.apache.commons.lang3.ArrayUtils;import org.springframework.beans.factory.BeanDefinitionStoreException;import org.springframework.context.ResourceLoaderAware;import org.springframework.core.io.Resource;import org.springframework.core.io.ResourceLoader;import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import org.springframework.core.io.support.ResourcePatternResolver;import org.springframework.core.io.support.ResourcePatternUtils;import org.springframework.core.type.classreading.CachingMetadataReaderFactory;import org.springframework.core.type.classreading.MetadataReader;import org.springframework.core.type.classreading.MetadataReaderFactory;import org.springframework.core.type.filter.AnnotationTypeFilter;import org.springframework.core.type.filter.TypeFilter;import org.springframework.util.StringUtils;import org.springframework.util.SystemPropertyUtils;import java.io.IOException;import java.lang.annotation.Annotation;import java.util.HashSet;import java.util.LinkedList;import java.util.List;import java.util.Set;public class ClassScaner implements ResourceLoaderAware {    //保存过滤规则要排除的注解    private final List<TypeFilter> includeFilters = new LinkedList<TypeFilter>();    private final List<TypeFilter> excludeFilters = new LinkedList<TypeFilter>();    private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();    private MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver);    public static Set<Class> scan(String[] basePackages,                                  Class<? extends Annotation>... annotations) {        ClassScaner cs = new ClassScaner();        if(ArrayUtils.isNotEmpty(annotations)) {            for (Class anno : annotations) {                cs.addIncludeFilter(new AnnotationTypeFilter(anno));            }        }        Set<Class> classes = new HashSet<Class>();        for (String s : basePackages)            classes.addAll(cs.doScan(s));        return classes;    }    public static Set<Class> scan(String basePackages, Class<? extends Annotation>... annotations) {        return ClassScaner.scan(StringUtils.tokenizeToStringArray(basePackages, ",; \t\n"), annotations);    }    public final ResourceLoader getResourceLoader() {        return this.resourcePatternResolver;    }    public void setResourceLoader(ResourceLoader resourceLoader) {        this.resourcePatternResolver = ResourcePatternUtils                .getResourcePatternResolver(resourceLoader);        this.metadataReaderFactory = new CachingMetadataReaderFactory(                resourceLoader);    }    public void addIncludeFilter(TypeFilter includeFilter) {        this.includeFilters.add(includeFilter);    }    public void addExcludeFilter(TypeFilter excludeFilter) {        this.excludeFilters.add(0, excludeFilter);    }    public void resetFilters(boolean useDefaultFilters) {        this.includeFilters.clear();        this.excludeFilters.clear();    }    public Set<Class> doScan(String basePackage) {        Set<Class> classes = new HashSet<Class>();        try {            String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX                    + org.springframework.util.ClassUtils                    .convertClassNameToResourcePath(SystemPropertyUtils                            .resolvePlaceholders(basePackage))                    + "/**/*.class";            Resource[] resources = this.resourcePatternResolver                    .getResources(packageSearchPath);            for (int i = 0; i < resources.length; i++) {                Resource resource = resources[i];                if (resource.isReadable()) {                    MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);                    if ((includeFilters.size() == 0 && excludeFilters.size() == 0)                            || matches(metadataReader)) {                        try {                            classes.add(Class.forName(metadataReader                                    .getClassMetadata().getClassName()));                        } catch (ClassNotFoundException e) {                            e.printStackTrace();                        }                    }                }            }        } catch (IOException ex) {            throw new BeanDefinitionStoreException(                    "I/O failure during classpath scanning", ex);        }        return classes;    }    protected boolean matches(MetadataReader metadataReader) throws IOException {        for (TypeFilter tf : this.excludeFilters) {            if (tf.match(metadataReader, this.metadataReaderFactory)) {                return false;            }        }        for (TypeFilter tf : this.includeFilters) {            if (tf.match(metadataReader, this.metadataReaderFactory)) {                return true;            }        }        return false;    }    public static void main(String[] args) {        ClassScaner.scan("com.hjzgg.test.thirdjar.config,com.hjzgg.test.thirdjar.web", null)            .forEach(clazz -> System.out.println(clazz));    }}

 

Spring根据包名获取包路径下的所有类