SpringBoot获取指定包下的各种资源

  • Post author:
  • Post category:其他




获取包路径下的资源


  • 场景介绍


    在一个需求里,我需要获取某个包路径下的所有类的方法,例如:我要获取

    com.it.hsrcm.pbs.api

    包路径下的所有方法名 (同理可以获取所有的类名等…)

    不得不说需求真的是奇奇怪怪,不怕遇不到,就怕百度的时候遇上那些神一样的文章,问题解决不了,叽里呱啦说了大半页,到了关键时刻公布真相的时候,他不行了,开始让你点赞了

  • 获取方式介绍


    通过实现

    SpringBoot

    的接口

    ResourceLoaderAware

    获取



一、包路径介绍



1.1 classpath: 的真实含义



  • classpath:

    指的是

    class

    路径前缀




    org.springframework.util.ResourceUtils.ResourceLoader

    中介绍了

    classpath:

    的作用,它和

    WEB-INF/

    的区别很大

    在这里插入图片描述


  • classpath:



    classpath*:

    的区别




    org.springframework.core.io.support.ResourcePatternResolver

    中说的很明白,大哥们的话简洁明了,只为少写一些注释,也让那些说不清区别的人别再出来祸祸其他的幼崽

    在这里插入图片描述



    classpath:

    只能找到一个,你必须还要写上这个文件的路径,但是用

    classpath*:

    ,你能拿到一切


  • Resource

    路径的种类


    我们常说的

    Resource

    指的是我们可以通过

    API

    加载到的任何一个资源,那么我们该如何通过路径去加载一个

    resource

    呢,在该类下面也给出了几种方式

    ① 通过绝对路径加载一个

    Resource

    例:

    file:C:/test.dat


    ② 通过类的伪路径加载一个

    Resource

    例:

    classpath:test.dat


    ③ 通过

    Resource

    的相对路径加载 例:

    WEB-INF/test.dat


    在这里插入图片描述



二、ResourceLoaderAware



2.1 实现ResourceLoaderAware接口

/**
	 * 资源扫描
	 *
	 * <p>扫描指定的包路径{@link #CLASS_SCAN_PACKAGE_PATH},获取包路劲想爱的所有
	 * {@link java.lang.Class}
	 */
	static class ScanSupport implements ResourceLoaderAware {

		private ResourceLoader resourceLoader = new PathMatchingResourcePatternResolver();
		private final ResourcePatternResolver resolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
		private final MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
		private static final String CLASS_SCAN_PACKAGE_PATH = "com.hundsun.hsrcm.pbs.api.rpc.service";

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

		/**
		 * 扫描公共接口包,获取所有的公共接口并加入白名单
		 *
		 * @return
		 * @throws IOException
		 */
		public Set<Class<?>> doScan() throws IOException {
			Set<Class<?>> classes = new HashSet<>();
			String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
					.concat(ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(CLASS_SCAN_PACKAGE_PATH))
							.concat("/**/*.class"));
			Resource[] resources = resolver.getResources(packageSearchPath);
			MetadataReader metadataReader = null;
			for (Resource resource : resources) {
				if (resource.isReadable()) {
					metadataReader = metadataReaderFactory.getMetadataReader(resource);
					try {
						classes.add(Class.forName(metadataReader.getClassMetadata().getClassName()));
					} catch (Exception e) {
						log.info("公共接口信息解析错误:{}", e.getMessage());
					}
				}
			}
			return classes;
		}
	}



2.2 源码分析

① 在

org.springframework.core.io

下提供了

ResourceLoader

接口



org.springframework.core.io.support

下的

ResourcePatternResolver

继承了上述接口

public interface ResourcePatternResolver extends ResourceLoader {

	String CLASSPATH_ALL_URL_PREFIX = "classpath*:";

	Resource[] getResources(String locationPattern) throws IOException;
}

③ 主要的方法为

PathMatchingResourcePatternResolver

该类下的

getResources(String locationParttern)


④ 这种方法主要去获取

locationParttern

为前面三种路径下的匹配项



版权声明:本文为hell_oword原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。