当前位置: 首页 > 知识库问答 >
问题:

Spring-batch@beforestep不能与@stepscope一起工作

魏明亮
2023-03-14

我使用的是Spring批处理版本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配置类中声明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定义为step范围的bean(这对于有状态的读取器更好),“Before step”代码就不再执行了。

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

我注意到处理器和writer bean也存在同样的问题。

提前感谢您的回答。

共有1个答案

岳和泽
2023-03-14

当您按照如下方式配置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版本2.2.4.RELEASE我试图用有状态的ItemReader,ItemProcessor和ItemWriter Bean编写一个简单的示例。 在集成测试中,我在内部静态java config类中声明我的bean,如下所示: 该测试通过。 但是,一旦我将 StatefulItemReader 定义为步域范围的bean(这对于有状态阅读器比较好),就

  • pom.xml版本信息: SpringFox-Swagger2:2.5.0 昂首阔步-核心:1.5.10 springfox-swagger-ui:2.6.1 Springboot:1.5.3 我有一个项目与swagger2和Springboot。 没有@Aspect的项目代码工作得很好。 正确的结果: 但是当我添加以下代码时,swagger-ui没有显示test-api-impl。 swagge

  • 当结合使用HystrixCodaHaleMetricsPublisher和Graphite时,我遇到了一个奇怪的问题。已创建度量节点,但未输入任何数据。 我的配置:

  • 更新:Oook,首先,非常感谢。我不知道用户是postgres中的保留关键字。我把名字改成了CustomUser,但现在问题是另外一个了,应用程序可以工作,但我注意到它创建了一个名为custom_user的相同的CustomUser表,因为它没有使用现有的表? 我刚开始使用Springboot,我不明白我错在哪里。这是我的模型: 希望在您的帮助下,非常感谢大家。

  • 根据它的Javadoc,将生成,其中的第一个值是subscribe和第一个next信号之间的经过时间。 以下测试不起作用 它将抛出异常: 我原以为经过的时间至少是1000ms,但结果只有11ms。

  • Selenium版本:2.41.0(作为Nuget包安装)OS:Windows7浏览器:Firefox浏览器版本:32