美文网首页
springboot 扫描指定包下的类

springboot 扫描指定包下的类

作者: hehehehe | 来源:发表于2020-07-16 10:44 被阅读0次

Spring提供了一个ResourcePatternResolver实现PathMatchingResourcePatternResolver,它是基于模式匹配的,默认使用AntPathMatcher进行路径匹配,它除了支持ResourceLoader支持的前缀外,还额外支持“classpath:”用于加载所有匹配的类路径Resource,ResourceLoader不支持前缀“classpath:”:
一、“classpath”: 用于加载类路径(包括jar包)中的一个且仅一个资源;对于多个匹配的也只返回一个,所以如果需要多个匹配的请考虑“classpath*:”前缀;
**二、“classpath*****”: 用于加载类路径(包括jar包)中的所有匹配的资源。带通配符的classpath使用“ClassLoader”的“Enumeration<URL> getResources(String name)”方法来查找通配符之前的资源,然后通过模式匹配来获取匹配的资源。如“classpath:META-INF/.LIST”将首先加载通配符之前的目录“META-INF”,然后再遍历路径进行子路径匹配从而获取匹配的资源。
三、“file”:加载一个或多个文件系统中的Resource。如“file:D:/
.txt”将返回D盘下的所有txt文件;

classpath

  1. src 路径下的文件 在编译后都会放到 classes 路径下。默认classpath 就是指这里。
  2. 用maven构建 项目时,resources 目录就是默认的classpath

classpath 与 classpath* 的区别

classpath classes 是一个定位资源入口, 目录下用来存放:
a1. 各种资源配置文件,eg.init.properties, log4j.properties, struts.xml
a2. 存放模板文件 eg.actionerror.ftl
a3. 编译后的class文件,对应的是项目开发时src目录编译文件
classpath* 不仅包含class路径,还包括jar文件中(class路径)进行查找.

@Slf4j
@Component
public class LayerNameBeans implements ResourceLoaderAware {

    private ResourceLoader resourceLoader;
    final String classPathPre = "classpath*:";
    final String adModelPackageName = "com.*.ads.processstore.domain.admodel";
    final String updModelPackageName = "com.*.ads.processstore.domain.updmodel";
    final String mapperPackageName = "com.*.ads.processstore.mapper";


    public Set<String> composedLayers = new HashSet<String>() {{
        add("ads_all.geojson");
        add("attrs.geojson");
        add("rels.geojson");
    }};
    public Set<String> singleLayers = new HashSet<>();

    public Map<String, String> layerIdMap = new HashMap<>();
    public Map<String, Class<?>> adMapperMap = new HashMap<>();
    public Map<String, Class<?>> adModelMap = new HashMap<>();

    public Map<String, Class<?>> updMapperMap = new HashMap<>();
    public Map<String, Class<?>> updModelMap = new HashMap<>();

    @PostConstruct
    void init() throws IOException, ClassNotFoundException {
        ClassLoader classLoader = LayerNameBeans.class.getClassLoader();
        ResourcePatternResolver resolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
        MetadataReaderFactory metaReader = new CachingMetadataReaderFactory(resourceLoader);

        getLayerIdMap(adModelPackageName, layerIdMap, classLoader,resolver, metaReader);
        getLayerModelMap(adModelPackageName, adModelMap,classLoader, resolver, metaReader);
        getLayerModelMap(updModelPackageName, updModelMap, classLoader,resolver, metaReader);
        getMapperMap(mapperPackageName, classLoader,resolver, metaReader);
        log.info("================layerIdMap {}",layerIdMap.size());
        log.info("================adModelMap {}",adModelMap.size());
        log.info("================updModelMap {}",updModelMap.size());
        log.info("================adMapperMap {}",adMapperMap.size());
        log.info("================updMapperMap {}",updMapperMap.size());
    }

    void getLayerIdMap(String packageName, Map<String, String> layerIdMap,ClassLoader classLoader ,
                       ResourcePatternResolver resolver, MetadataReaderFactory metaReader) throws IOException, ClassNotFoundException {

        Resource[] resources = resolver.getResources(classPathPre +
                packageName.replace('.', '/') + "/*.class");
        for (Resource r : resources) {
            MetadataReader reader = metaReader.getMetadataReader(r);
            String className = reader.getClassMetadata().getClassName();
            Class<?> clz = classLoader.loadClass(className);
            LayerName layerNameAnnotation = clz.getDeclaredAnnotation(LayerName.class);
            PrimaryField primaryAnnotation = clz.getDeclaredAnnotation(PrimaryField.class);
            if (layerNameAnnotation != null && primaryAnnotation != null) {
                singleLayers.add(layerNameAnnotation.value() + ".geojson");
                layerIdMap.put(layerNameAnnotation.value(), primaryAnnotation.value());
            }
        }
    }

    void getMapperMap(String packageName,ClassLoader classLoader , ResourcePatternResolver resolver,
                      MetadataReaderFactory metaReader) throws IOException, ClassNotFoundException {
        Resource[] resources = resolver.getResources(classPathPre +
                packageName.replace('.', '/') + "/*.class");
        for (Resource r : resources) {
            MetadataReader reader = metaReader.getMetadataReader(r);
            String className = reader.getClassMetadata().getClassName();
            Class<?> clz = classLoader.loadClass(className);
            LayerName layerNameAnnotation = clz.getDeclaredAnnotation(LayerName.class);
            if (layerNameAnnotation != null) {
                String layerName = layerNameAnnotation.value();
                if (className.contains("Upd")) {
                    updMapperMap.put(layerName, clz);
                }else if(className.contains("Ad")){
                    adMapperMap.put(layerName, clz);
                }
            }
        }
    }

    void getLayerModelMap(String packageName, Map<String, Class<?>> map, ClassLoader classLoader ,ResourcePatternResolver resolver,
                          MetadataReaderFactory metaReader) throws IOException, ClassNotFoundException {
        Resource[] resources = resolver.getResources(classPathPre +
                packageName.replace('.', '/') + "/*.class");
        for (Resource r : resources) {
            MetadataReader reader = metaReader.getMetadataReader(r);
            String className = reader.getClassMetadata().getClassName();
            Class<?> clz = classLoader.loadClass(className);
            LayerName layerNameAnnotation = clz.getDeclaredAnnotation(LayerName.class);
            if (layerNameAnnotation != null) {
                singleLayers.add(layerNameAnnotation.value() + ".geojson");
                map.put(layerNameAnnotation.value(), clz);
            }
        }
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

}

相关文章

网友评论

      本文标题:springboot 扫描指定包下的类

      本文链接:https://www.haomeiwen.com/subject/fpxphktx.html