当前位置: 首页 > 面试题库 >

Spring-Batch @BeforeStep不适用于@StepScope

林子石
2023-03-14
问题内容

我正在使用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存在相同的问题。

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

我的带有多个JUnit测试的整个Maven项目可以在GitHub上找到: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。正确MyInterfaceImpl的配置方法是返回您的配置方法,如下所示:

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

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



 类似资料:
  • 我使用的是Spring批处理版本2.2.4.Release,我试图用有状态的ItemReader、ItemProcessor和ItemWriter bean编写一个简单的示例。 在我的集成测试中,我在一个内部静态java配置类中声明bean,如下所示: 这个测试通过了。 但是,一旦我将StatefulItemReader定义为step范围的bean(这对于有状态的读取器更好),“Before st

  • 我有一个实体: 而听众: 我正在使用为这个实体(1.4.1)和EclipseLink生成的Spring Data。代码行为如下所示: 这个问题在2009年已经有人描述过了,但是他们没有提出任何解决方案。不知道有没有人有办法解决?

  • 我试图用Kotlin在spring boot应用程序中懒洋洋地初始化bean。 我有一个spring@配置文件,其中有一个延迟注释的bean: 我有一个rest控制器,在那里我懒散地自动连接bean 我正在访问某个RequestMapping中的类中的变量 我在方法中添加了日志,并确认bean没有急切地初始化。问题是即使在访问时也没有初始化。该类是一个简单的开放类。 bean初始化从未发生过。我不

  • 当我使用这样的routes statique时,我正在使用Spring cloud gateway(它工作得很好): 但是,当我想将routes Dynamicque与DiscoveryClientRoutedDefinitionLocator一起使用时,我的功能是: 这是我的申请表。属性: 当我叫这个urihttp://localhost:8888/PRODUCT-SERVICE/product

  • 我正在开发一个Spring Boot项目,目前正在尝试实现验证。例如,我有以下类: 包abcdef.mypackage 您可以看到,我已经用我想要的验证对所有字段进行了注释。传入请求由以下控制器类处理: 当我现在用一个空的用户名值发出请求时,Spring Boot仍然接受它并存储到数据库中。我在StackOverflow上找到了一些关于缺少依赖项的问题(和答案),但是我把它们都包括进来了。你可以在

  • 我正在尝试让Spring事务管理在我的新Spring Boot MyBatis应用程序中工作。 到目前为止,我已经设法让一切都以最小的问题工作——它只是让注释正常运行。目前,无论方法是否被注释,所有语句都会立即提交。 Spring Boot为您提供了如此多的样板配置,以至于很难找到丢失的链接。 我的包含以下依赖项: 我的包含以下数据源配置: bean中不按预期运行的方法的一个简单示例如下: 引发异