如何获得我不“拥有”的自动assembly器

要点是Spring Batch(v2)测试框架具有带@Autowired注释的JobLauncherTestUtils.setJob 。 我们的测试套件有多个Job类提供程序。 由于这个类不是我可以修改的,所以我不确定如何确定它自动assembly哪个作业,每个测试可能会有所不同。

  STDOUT [WARN ] [2015.04.15 11:14:42] support.GenericApplicationContext - Exception encountered during context initialization - cancelling refresh attempt org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jobLauncherTestUtilsForSnapshot': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.batch.test.JobLauncherTestUtils.setJob(org.springframework.batch.core.Job); nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.batch.core.Job] is defined: expected single matching bean but found 2: coverageRuleBatch,generateMetricsSnapshotJob 

我已经尝试添加这个被识别的JavaConfig,但错误说它仍然是自动setJob

 @Configuration public class SpringTestConfiguration { @Bean public JobLauncherTestUtils jobLauncherTestUtilsForSnapshot( final Job generateMetricsSnapshotJob ) { JobLauncherTestUtils jobLauncherTestUtils = new JobLauncherTestUtils(); jobLauncherTestUtils.setJob( generateMetricsSnapshotJob ); return jobLauncherTestUtils; } } 

注意:我不需要JavaConfig解决方案,但它会很好。 另外,如果可能的话,我想仍然像JobRepository这样的Autowire字段,因为只有一个。

当我遇到同样的问题时,我的解决方案是限制组件扫描,以便在测试上下文中只创建一个Job bean。

 @Configuration @ComponentScan(basePackages={ "com.example.batch.jobs.metrics", //package where generateMetricsSnapshotJob is the only job "com.example.batch.common", "..." }) public class SpringTestConfiguration { @Bean public JobLauncherTestUtils jobLauncherTestUtils() { //generateMetricsSnapshotJob and other requirements will be autowired return new JobLauncherTestUtils(); } } 

您可能需要调整包结构才能使其正常工作。

我提出的解决方案

 @Configuration public class SpringBatchTestConfiguration { @Bean public static JobLauncherTestUtils jobLauncherTestUtilsForSnapshot() { return new SnapshotJobLauncherTestUtils(); } public static class SnapshotJobLauncherTestUtils extends JobLauncherTestUtils { @Override @Qualifier( "generateMetricsSnapshotJob" ) public void setJob( final Job job ) { super.setJob( job ); } } } 

并在最后的测试中

 @Autowired @Qualifier( "jobLauncherTestUtilsForSnapshot" ) protected JobLauncherTestUtils jobLauncherTestUtils; 

相当自信我可以用@Component注释我的TestUtils并正确命名并做同样的事情。

其他类型的解决方案是通过setter注入它。 我更喜欢这种解决方案,因为它更清晰,更容易。

 @Configuration public class SpringTestConfiguration { @Bean public JobLauncherTestUtils jobLauncherTestUtilsForSnapshot() { return new JobLauncherTestUtils() { @Override @Autowired public void setJob(@Qualifier("generateMetricsSnapshotJob") Job job) { super.setJob(job); } }; } } 

也许您可以使用Spring配置文件。 为每个Job提供程序bean定义分配不同的配置文件(使用注释@Profile("profileName") ,然后使用注释@ActiveProfiles("profileName")激活特定测试类上正确提供程序的配置文件。

  1. 您可以扩展AutowiredAnnotationBeanPostProcessor并覆盖注入方法。

  2. 删除条目

  3. 注册你的bean