Spring根据包名搜索类

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载自夜明的孤行灯

本文链接地址: https://www.huangyunkun.com/2015/02/28/spring-search-class-by-package/

有时候我们会遇到这种情况,需要根据动态获取某个包下的一些特定类。

比如获取”com.xxx.domain”下所有类。

Spring中ClassPathScanningCandidateComponentProvider可以快速完成这项任务。

Spring最核心的一个部分就是Ioc,通过@Component来注解需要委托管理的类。

ClassPathScanningCandidateComponentProvider提供了一个默认的过滤器来处理Component。

protectedvoidregisterDefaultFilters() {
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(((Class < ?extends Annotation > ) ClassUtils.forName("javax.annotation.ManagedBean", cl)),false));
logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}catch(ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
}
try {
this.includeFilters.add(new AnnotationTypeFilter(((Class < ?extends Annotation > ) ClassUtils.forName("javax.inject.Named", cl)),false));
logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}catch(ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}

当然,我们不需要这个过滤器,所以在实例化ClassPathScanningCandidateComponentProvider时传入参数false。

我们可以自定义过滤器来做一些逻辑相关的东西,比如加载以Task结尾的类。

final ClassPathScanningCandidateComponentProvider provider =new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new RegexPatternTypeFilter(Pattern.compile(".*Task")));
final Set < BeanDefinition > classes = provider.findCandidateComponents("cn.acgmo.job");
for (BeanDefinition bean: classes) {
jobClasses.add(Class.forName(bean.getBeanClassName()));
}

虽然还有一个很方便的Reflection库可以选择,但是大部分情况下Spring就足够了。

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载自夜明的孤行灯

本文链接地址: https://www.huangyunkun.com/2015/02/28/spring-search-class-by-package/

发表评论