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

获取包路径下的资源

  • 场景介绍
    在一个需求里,我需要获取某个包路径下的所有类的方法,例如:我要获取 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 为前面三种路径下的匹配项

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值