Spring-batch @BeforeStep不适用于@StepScope

我正在使用Spring Batch版本2.2.4.RELEASE我试着用有状态的ItemReader,ItemProcessor和ItemWriter bean编写一个简单的例子。

public class StatefulItemReader implements ItemReader { private List list; @BeforeStep public void initializeState(StepExecution stepExecution) { this.list = new ArrayList(); } @AfterStep public ExitStatus exploitState(StepExecution stepExecution) { System.out.println("******************************"); System.out.println(" READING RESULTS : " + list.size()); return stepExecution.getExitStatus(); } @Override public String read() throws Exception { this.list.add("some stateful reading information"); if (list.size() < 10) { return "value " + list.size(); } return null; } } 

在我的集成测试中,我在一个内部静态java配置类中声明我的bean,如下所示:

 @ContextConfiguration @RunWith(SpringJUnit4ClassRunner.class) public class SingletonScopedTest { @Configuration @EnableBatchProcessing static class TestConfig { @Autowired private JobBuilderFactory jobBuilder; @Autowired private StepBuilderFactory stepBuilder; @Bean JobLauncherTestUtils jobLauncherTestUtils() { return new JobLauncherTestUtils(); } @Bean public DataSource dataSource() { EmbeddedDatabaseBuilder embeddedDatabaseBuilder = new EmbeddedDatabaseBuilder(); return embeddedDatabaseBuilder.addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql") .addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql") .setType(EmbeddedDatabaseType.HSQL) .build(); } @Bean public Job jobUnderTest() { return jobBuilder.get("job-under-test") .start(stepUnderTest()) .build(); } @Bean public Step stepUnderTest() { return stepBuilder.get("step-under-test") .chunk(1) .reader(reader()) .processor(processor()) .writer(writer()) .build(); } @Bean public ItemReader reader() { return new StatefulItemReader(); } @Bean public ItemProcessor processor() { return new StatefulItemProcessor(); } @Bean public ItemWriter writer() { return new StatefulItemWriter(); } } @Autowired JobLauncherTestUtils jobLauncherTestUtils; @Test public void testStepExecution() { JobExecution jobExecution = jobLauncherTestUtils.launchStep("step-under-test"); assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus()); } } 

这个测试通过。

但是一旦我将StatefulItemReader定义为步骤范围的bean(对于有状态的读者来说更好),就不再执行“before step”代码了。

 ... @Bean @StepScope public ItemReader reader() { return new StatefulItemReader(); } ... 

我注意到处理器和我的编写器bean的相同问题。

我的代码出了什么问题? 是否与此已解决的问题有关: https : //jira.springsource.org/browse/BATCH-1230

我可以在GitHub上找到我的几个JUnit测试的整个Maven项目: https : //github.com/galak75/spring-batch-step-scope

提前感谢您的回答。

配置bean时如下:

 @Bean @StepScope public MyInterface myBean() { return new MyInterfaceImpl(); } 

你告诉Spring使用代理模式ScopedProxyMode.TARGET_CLASS 。 但是,通过返回MyInterface而不是MyInterfaceImpl ,代理只能看到MyInterface上的方法。 这可以防止Spring Batch在MyInterfaceImpl上找到已经使用@BeforeStep等监听器注释注释的@BeforeStep 。 配置它的正确方法是在配置方法上返回MyInterfaceImpl ,如下所示:

 @Bean @StepScope public MyInterfaceImpl myBean() { return new MyInterfaceImpl(); } 

我们在启动时添加了一条警告日志消息,指出当我们查找带注释的侦听器方法时,如果对象被代理并且目标是接口,我们将无法在带有注释的实现类上找到方法他们。