一.Reflections
maven:
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.10.2</version>
</dependency>
代码(最终版)
//配置扫描com.zzx包下的类
Reflections f = new Reflections("[\\s\\S]*com.zzx");
//Reflections f = new Reflections(ConfigurationBuilder.build("com.zzz","BOOT-INF.classes.com.zzz"));
// 获取扫描到的标记注解的集合
Set<Class<?>> set = f.getTypesAnnotatedWith(Data.class);
set.stream().forEach(System.out::println);
问题点:
1.
问题:一开始配置 new Reflections("com.zzx"),结果本地可以扫描到,但打包后却扫描不到
原因:配置 new Reflections("com.zzx") 是通过正则 com\.zzx\..* 进行匹配的,而spring打包后拿到的类路径有 BOOT-INF/classes的前缀,即 BOOT-INF/classes/com.zzx 是无法匹配正则的
匹配规则相关代码在下面的doFilter里:
解决:
① 配置 new Reflections("[\\s\\S]*com.zzx") ,这样会通过正则 [\s\S]*com.zzx\..* 匹配,即 com.zzx 前缀匹配任意字符
② 配置 new Reflections(ConfigurationBuilder.build("com.zzz","BOOT-INF.classes.com.zzz")) 多个路径,或者根据环境配置特定路径。配置单个路径扫描性能应该比前一种好点.
2. 此处注意不能用 "." 替代 [\s\S] ,因为 Reflections 会把路径上的所有 "." 进行转义,导致无法匹配,相关代码如下
二.spring 扫描,
spring的没有啥问题,直接上代码就好了
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
//此处如果要用扫描注解可以用AnnotationTypeFilter
scanner.addIncludeFilter(new AssignableTypeFilter(Object.class));
Set<BeanDefinition> beanDefinitionSet = scanner.findCandidateComponents("com.zzx");
for (BeanDefinition beanDefinition : beanDefinitionSet) {
String beanClassName = beanDefinition.getBeanClassName();
Class<?> clazz = null;
try {
clazz = Class.forName(beanClassName);
} catch (ClassNotFoundException e) {
throw new RuntimeException(beanClassName + "找不到", e);
}
}