【问题标题】:Unit tests very slow because spring classpath scanning scans multiple times the same package单元测试非常慢,因为 spring 类路径扫描多次扫描同一个包
【发布时间】:2016-08-07 13:04:25
【问题描述】:

将 Spring 3 与 spring 数据一起使用,我有一个包 com.company.repository,其中包含与 spring 数据存储库相关的所有类(大约 50 个类)。

组件扫描声明为:

<context:component-scan base-package="com.company"/>

在我的单元测试中,扫描弹簧组件的步骤很长(大约 10 秒)。 启用跟踪日志后,我注意到包“com.company.repository”被扫描了多次。 实际上,ClassPathScanningCandidateComponentProvider.findCandidateComponents("com.company.repository") 方法被调用了多次,其值相同。 我不明白为什么我有这种行为。 而且我不会通过自定义实现来覆盖它(或者我找不到如何做到这一点)。 而且我不明白为什么默认实现中没有缓存?

有人知道我为什么会有这种行为吗?正常吗?

作为补充,以下是与我的案例相关的堆栈:

ClassPathScanningCandidateComponentProvider.findCandidateComponents(String) line: 224   
RepositoryBeanDefinitionBuilder.detectCustomImplementation(BeanDefinitionRegistry, ResourceLoader) line: 154    
RepositoryBeanDefinitionBuilder.registerCustomImplementation(BeanDefinitionRegistry, ResourceLoader) line: 116  
RepositoryBeanDefinitionBuilder.build(BeanDefinitionRegistry, ResourceLoader) line: 97  
RepositoryBeanDefinitionParser.registerGenericRepositoryFactoryBean(RepositoryConfiguration<XmlRepositoryConfigurationSource>, ParserContext) line: 101 
RepositoryBeanDefinitionParser.parse(Element, ParserContext) line: 71   
JpaRepositoryNameSpaceHandler(NamespaceHandlerSupport).parse(Element, ParserContext) line: 73   
BeanDefinitionParserDelegate.parseCustomElement(Element, BeanDefinition) line: 1419 
BeanDefinitionParserDelegate.parseCustomElement(Element) line: 1409 
DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(Element,  BeanDefinitionParserDelegate) line: 184  
...
XmlBeanDefinitionReader.doLoadBeanDefinitions(InputSource, Resource) line: 390

【问题讨论】:

  • 如果您依赖 Spring 创建 bean,我不会将其称为单元测试。这听起来更像是集成测试。

标签: java spring unit-testing junit spring-data


【解决方案1】:

也许您的测试配置为在每次测试后创建和销毁您的 spring 上下文。 检查您的测试基础配置。

【讨论】:

  • 即使只有 1 次测试也是如此。
  • 经过一番调查,我注意到注册整个存储库类的启动时间很长。所以我想用自定义过滤器排除一些我不需要测试的存储库类。但是“RepositoryBeanDefinitionBuilder”bean 没有考虑到我的过滤器。我注意到在春季启动时有 2 种不同的扫描器: ClassPathScanningCandidateComponentProvider => 我的过滤器被考虑到 RepositoryComponentProvider => 我的过滤器没有被考虑在内。如何从第二个提供者 (RepositoryComponentProvider) 中排除类?
  • 您可以尝试从组件扫描中删除您的存储库包吗?并在扫描存储库选项中指定此路径。
  • 我可以从组件扫描中排除我的存储库路径。但是如何在扫描存储库选项中指定此路径?
  • 有一个指定 jpa 存储库的注释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-21
  • 2016-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-28
相关资源
最近更新 更多