Spring-Batch @BeforeStep不适用于@StepScope
我正在使用Spring Batch版本2.2.4.RELEASE我试图用有状态的ItemReader,ItemProcessor和ItemWriter Bean编写一个简单的示例。
public class StatefulItemReader implements ItemReader<String> {    private List<String> 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 config类中声明我的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")
                    .<String, String>chunk(1)
                    .reader(reader())
                    .processor(processor())
                    .writer(writer())
                    .build();
        }
        @Bean
        public ItemReader<String> reader() {
            return new StatefulItemReader();
        }
        @Bean
        public ItemProcessor<String, String> processor() {
            return new StatefulItemProcessor();
        }
        @Bean
        public ItemWriter<String> 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(这对于有状态阅读器比较好),就不再执行“步骤前”代码。
...    @Bean
    @StepScope
    public ItemReader<String> reader() {
        return new StatefulItemReader();
    }
...
而且我注意到处理器和我的编写器bean存在相同的问题。
回答:
当你按如下方式配置bean时:
@Bean@StepScope
public MyInterface myBean() {
    return new MyInterfaceImpl();
}
你正在告诉Spring使用代理模式ScopedProxyMode.TARGET_CLASS。但是,通过返回MyInterface而不是返回,MyInterfaceImpl代理仅具有对上方法的可见性MyInterface。这将阻止Spring Batch能够在MyInterfaceImpl已使用侦听器注释(例如)进行注释的方法上找到方法@BeforeStep。正确MyInterfaceImpl的配置方法是返回你的配置方法,如下所示:
@Bean@StepScope
public MyInterfaceImpl myBean() {
    return new MyInterfaceImpl();
}
我们在启动时添加了一条警告日志消息,该消息指出,当我们寻找带注释的侦听器方法时,如果该对象被代理并且目标是接口,则将无法在实现类上找到带有注释的方法他们。
以上是 Spring-Batch @BeforeStep不适用于@StepScope 的全部内容, 来源链接: utcz.com/qa/435928.html








