[SPRING] Spring 배치 @BeforeStep은 @StepScope와 작동하지 않습니다.
SPRINGSpring 배치 @BeforeStep은 @StepScope와 작동하지 않습니다.
Spring Batch 버전 2.2.4를 사용하고 있습니다. Stateful ItemReader, ItemProcessor 및 ItemWriter 빈을 사용하여 간단한 예제를 작성하려고했습니다.
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;
}
}
내 통합 테스트에서 내 bean을 내부 static java config 클래스에 다음과 같이 선언하고있다.
@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 (상태 저장 판독기에 더 좋음)으로 정의하는 즉시 "before step"코드가 더 이상 실행되지 않습니다.
...
@Bean
@StepScope
public ItemReader<String> reader() {
return new StatefulItemReader();
}
...
그리고 나는 프로세서와 필자의 빈에 대해서도 똑같은 문제에 주목합니다.
내 코드에 무슨 문제가 있습니까? 이 문제와 관련이 있습니까? https://jira.springsource.org/browse/BATCH-1230
몇 가지 JUnit 테스트가 포함 된 Maven 프로젝트는 GitHub에서 찾을 수 있습니다. https://github.com/galak75/spring-batch-step-scope
미리 답변 해 주셔서 감사합니다.
해결법
-
==============================
1.다음과 같이 bean을 구성 할 때 :
다음과 같이 bean을 구성 할 때 :
@Bean @StepScope public MyInterface myBean() { return new MyInterfaceImpl(); }
ScopedProxyMode.TARGET_CLASS 프록시 모드를 사용하도록 Spring에 지시하고있다. 그러나 MyInterfaceImpl 대신 MyInterface를 반환하면 프록시가 MyInterface의 메서드에 대한 가시성 만 갖습니다. 이렇게하면 Spring Batch가 @BeforeStep과 같은 리스너 주석으로 주석 처리 된 MyInterfaceImpl의 메소드를 찾을 수 없게됩니다. 이를 구성하는 올바른 방법은 MyInterfaceImpl을 아래와 같은 구성 방법으로 반환하는 것입니다.
@Bean @StepScope public MyInterfaceImpl myBean() { return new MyInterfaceImpl(); }
시작할 때 경고 로그 메시지가 추가되었습니다. 주석이 달린 리스너 메소드를 찾을 때 객체가 프록시되고 타겟이 인터페이스 인 경우 주석이있는 구현 클래스의 메소드를 찾을 수 없습니다 그들.
from https://stackoverflow.com/questions/21241683/spring-batch-beforestep-does-not-work-with-stepscope by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 읽을 수있는 로그를 갖기 위해 Spring 로그를 사용 불가능하게한다. (0) | 2019.01.01 |
---|---|
[SPRING] @Transactional의 이상한 동작 (propagation = Propagation.REQUIRES_NEW) (0) | 2019.01.01 |
[SPRING] Spring @Async v 호출 가능 컨트롤러 (비동기 컨트롤러, 서블릿 3) (0) | 2019.01.01 |
[SPRING] 언제 봄 콩 파괴 방법이라고? (0) | 2019.01.01 |
[SPRING] 비 싱글 톤 빈에서 캐스팅 된 스프링 프록시에서 BeanNotOfRequiredTypeException 수정? (0) | 2019.01.01 |