zoukankan      html  css  js  c++  java
  • 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, ",; 	
    "), 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));
        }
    }
  • 相关阅读:
    一个别人的心得(转发的)
    常见的游戏设计技术
    查看更新
    xml,json和各种序列化工具的对比
    python游戏环境搭建
    快速制作游戏
    子网和掩码
    nat
    pycharm使用技巧
    IP的面向无连接状态
  • 原文地址:https://www.cnblogs.com/hujunzheng/p/7284280.html
Copyright © 2011-2022 走看看