1. 개요
Spring Batch 는 강력한 배치 애플리케이션을 개발하기위한 강력한 프레임 워크입니다. 이전 예제에서 Spring Batch를 소개했습니다 .
이 예제에서는 이전 버전을 기반으로 Spring Boot를 사용하여 기본 배치 기반 애플리케이션을 설정하고 만드는 방법을 배웁니다 .
2. Maven 의존성
먼저 spring-boot-starter-batch 를 pom.xml에 추가해 보겠습니다 .
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
<version>2.4.0</version>
</dependency>
또한 Maven Central 에서 사용할 수 있는 org.hsqldb 의존성 도 추가합니다 .
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.5.1</version>
<scope>runtime</scope>
</dependency>
3. 간단한 스프링 배치 작업 정의
CSV 파일에서 커피 List을 가져 와서 사용자 지정 프로세서를 사용하여 변환하고 최종 결과를 메모리 내 데이터베이스에 저장하는 작업을 빌드 할 것입니다 .
3.1. 시작하기
애플리케이션 진입 점을 정의하여 시작하겠습니다.
@SpringBootApplication
public class SpringBootBatchProcessingApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootBatchProcessingApplication.class, args);
}
}
보시다시피 이것은 표준 Spring Boot 애플리케이션입니다. 가능한 경우 기본 구성 값을 사용하기를 원하므로 매우 간단한 응용 프로그램 구성 속성 집합을 사용합니다.
src / main / resources / application.properties 파일 에서 이러한 속성을 정의 합니다.
file.input=coffee-list.csv
이 속성은 입력 커피 List의 위치를 포함합니다. 각 라인에는 브랜드, 원산지 및 커피의 일부 특성이 포함됩니다.
Blue Mountain,Jamaica,Fruity
Lavazza,Colombia,Strong
Folgers,America,Smokey
보시 겠지만 이것은 평범한 CSV 파일입니다. 이는 Spring이 특별한 사용자 정의없이 처리 할 수 있음을 의미합니다.
다음으로 SQL 스크립트 schema-all.sql 을 추가 하여 데이터를 저장할 커피 테이블을 만듭니다 .
DROP TABLE coffee IF EXISTS;
CREATE TABLE coffee (
coffee_id BIGINT IDENTITY NOT NULL PRIMARY KEY,
brand VARCHAR(20),
origin VARCHAR(20),
characteristics VARCHAR(30)
);
편리하게 Spring Boot는 시작 중에이 스크립트를 자동으로 실행합니다 .
3.2. 커피 도메인 클래스
그 후, 커피 아이템을 보관하기위한 간단한 도메인 클래스가 필요합니다.
public class Coffee {
private String brand;
private String origin;
private String characteristics;
public Coffee(String brand, String origin, String characteristics) {
this.brand = brand;
this.origin = origin;
this.characteristics = characteristics;
}
// getters and setters
}
앞서 언급했듯이 Coffee 객체에는 세 가지 속성이 있습니다.
- 브랜드
- 기원
- 몇 가지 추가 특성
4. 작업 구성
이제 핵심 구성 요소 인 작업 구성으로 넘어갑니다. 단계별로 구성을 구축하고 각 부분을 설명합니다.
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Value("${file.input}")
private String fileInput;
// ...
}
먼저 표준 Spring @Configuration 클래스로 시작 합니다. 다음으로 클래스에 @EnableBatchProcessing 어노테이션을 추가합니다 . 특히, 이것은 우리에게 작업을 지원하고 많은 다리 작업을 절약 할 수있는 많은 유용한 빈에 대한 액세스를 제공합니다.
또한이 어노테이션을 사용하면 나중에 작업 구성 및 작업 단계를 빌드 할 때 사용할 두 개의 유용한 팩토리에 액세스 할 수 있습니다.
초기 구성의 마지막 부분에서는 이전에 선언 한 file.input 속성에 대한 참조를 포함합니다 .
4.1. 우리 직업의 독자이자 작가
이제 구성에서 리더 빈을 정의 할 수 있습니다.
@Bean
public FlatFileItemReader reader() {
return new FlatFileItemReaderBuilder().name("coffeeItemReader")
.resource(new ClassPathResource(fileInput))
.delimited()
.names(new String[] { "brand", "origin", "characteristics" })
.fieldSetMapper(new BeanWrapperFieldSetMapper() {{
setTargetType(Coffee.class);
}})
.build();
}
간단히 말해 위에서 정의한 리더 빈은 coffee-list.csv 라는 파일을 찾고 각 라인 항목을 Coffee 객체 로 구문 분석 합니다 .
마찬가지로 writer bean을 정의합니다.
@Bean
public JdbcBatchItemWriter writer(DataSource dataSource) {
return new JdbcBatchItemWriterBuilder()
.itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
.sql("INSERT INTO coffee (brand, origin, characteristics) VALUES (:brand, :origin, :characteristics)")
.dataSource(dataSource)
.build();
}
이번에는 Coffee 객체 의 Java bean 속성에 따라 단일 커피 항목을 데이터베이스에 삽입하는 데 필요한 SQL 문을 포함 합니다. 편리하게 dataSource 는 @EnableBatchProcessing 어노테이션에 의해 자동으로 생성됩니다 .
4.2. 우리의 직업을 하나로
마지막으로 실제 작업 단계와 구성을 추가해야합니다.
@Bean
public Job importUserJob(JobCompletionNotificationListener listener, Step step1) {
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer())
.listener(listener)
.flow(step1)
.end()
.build();
}
@Bean
public Step step1(JdbcBatchItemWriter writer) {
return stepBuilderFactory.get("step1")
.<Coffee, Coffee> chunk(10)
.reader(reader())
.processor(processor())
.writer(writer)
.build();
}
@Bean
public CoffeeItemProcessor processor() {
return new CoffeeItemProcessor();
}
보시다시피, 우리의 작업은 비교적 간단하며 step1 방법에 정의 된 하나의 단계로 구성됩니다 .
이 단계가 수행하는 작업을 살펴 보겠습니다.
- 먼저 chunk (10) 선언을 사용하여 한 번에 최대 10 개의 레코드를 쓰도록 단계를 구성합니다.
- 그런 다음 리더 메소드를 사용하여 설정 한 리더 빈을 사용하여 커피 데이터를 읽습니다.
- 다음으로, 우리는 각각의 커피 아이템을 커스텀 비즈니스 로직을 적용하는 커스텀 프로세서로 전달합니다.
- 마지막으로 이전에 본 작가를 사용하여 각 커피 항목을 데이터베이스에 씁니다.
반면에 importUserJob 에는 빌드 된 RunIdIncrementer 클래스를 사용하는 ID가 포함 된 작업 정의가 포함되어 있습니다 . 또한 JobCompletionNotificationListener를 설정 하여 작업이 완료 될 때 알림을받습니다 .
작업 구성을 완료하기 위해 각 단계를 나열합니다 (이 작업에는 단계가 하나만 있음). 이제 완벽하게 구성된 작업이 생겼습니다!
5. 맞춤형 커피 프로세서
이전에 작업 구성에서 정의한 사용자 지정 프로세서를 자세히 살펴 보겠습니다.
public class CoffeeItemProcessor implements ItemProcessor<Coffee, Coffee> {
private static final Logger LOGGER = LoggerFactory.getLogger(CoffeeItemProcessor.class);
@Override
public Coffee process(final Coffee coffee) throws Exception {
String brand = coffee.getBrand().toUpperCase();
String origin = coffee.getOrigin().toUpperCase();
String chracteristics = coffee.getCharacteristics().toUpperCase();
Coffee transformedCoffee = new Coffee(brand, origin, chracteristics);
LOGGER.info("Converting ( {} ) into ( {} )", coffee, transformedCoffee);
return transformedCoffee;
}
}
특히 흥미로운 점은 ItemProcessor 인터페이스가 작업 실행 중에 특정 비즈니스 로직을 적용하는 메커니즘을 제공 한다는 것입니다.
간단하게하기 위해 우리는 CoffeeItemProcessor를 정의합니다. CoffeeItemProcessor 는 입력 Coffee 객체를 받고 각 속성을 대문자로 변환합니다 .
6. 작업 완료
또한 작업이 완료되면 피드백을 제공하기 위해 JobCompletionNotificationListener 를 작성합니다 .
@Override
public void afterJob(JobExecution jobExecution) {
if (jobExecution.getStatus() == BatchStatus.COMPLETED) {
LOGGER.info("!!! JOB FINISHED! Time to verify the results");
String query = "SELECT brand, origin, characteristics FROM coffee";
jdbcTemplate.query(query, (rs, row) -> new Coffee(rs.getString(1), rs.getString(2), rs.getString(3)))
.forEach(coffee -> LOGGER.info("Found < {} > in the database.", coffee));
}
}
위의 예에서는 afterJob 메서드를 재정의 하고 작업이 성공적으로 완료되었는지 확인합니다. 또한 각 커피 항목이 데이터베이스에 성공적으로 저장되었는지 확인하기 위해 간단한 쿼리를 실행합니다 .
7. 작업 실행
이제 작업을 수행 할 모든 것이 준비되었으므로 여기에 재미있는 부분이 있습니다. 계속해서 작업을 실행 해 보겠습니다.
...
17:41:16.336 [main] INFO c.b.b.JobCompletionNotificationListener -
!!! JOB FINISHED! Time to verify the results
17:41:16.336 [main] INFO c.b.b.JobCompletionNotificationListener -
Found < Coffee [brand=BLUE MOUNTAIN, origin=JAMAICA, characteristics=FRUITY] > in the database.
17:41:16.337 [main] INFO c.b.b.JobCompletionNotificationListener -
Found < Coffee [brand=LAVAZZA, origin=COLOMBIA, characteristics=STRONG] > in the database.
17:41:16.337 [main] INFO c.b.b.JobCompletionNotificationListener -
Found < Coffee [brand=FOLGERS, origin=AMERICA, characteristics=SMOKEY] > in the database.
...
보시다시피 작업이 성공적으로 실행되었으며 각 커피 항목은 예상대로 데이터베이스에 저장되었습니다 .
8. 결론
이 기사에서는 Spring Boot를 사용하여 간단한 Spring Batch 작업을 만드는 방법을 배웠습니다. 먼저 몇 가지 기본 구성을 정의하는 것으로 시작했습니다.
그런 다음 파일 판독기와 데이터베이스 작성기를 추가하는 방법을 보았습니다. 마지막으로 사용자 지정 처리를 적용하고 작업이 성공적으로 실행되었는지 확인하는 방법을 살펴 보았습니다.
- https://docs.spring.io/spring-framework/docs/current/reference/html
- https://www.baeldung.com/spring-boot-spring-batch
'Java' 카테고리의 다른 글
이미지를 Base64 문자열로 변환 (0) | 2021.03.25 |
---|---|
Java에서 재귀 적으로 디렉토리 삭제 (0) | 2021.03.24 |
자바에서 바이너리 트리 구현 (0) | 2021.03.24 |
자바의 MD5 해싱 (0) | 2021.03.24 |
Java의 접기 기술에 대한 사용방법(예제) (0) | 2021.03.24 |