ํ๊ฒฝ ์ค์ ๋ง์น๊ณ ๋ฐฐ์น ์์ํ๋ค ใ ใ
Spring Boot 2.7.5 , Maven , Java 11
Library : Spring Boot DevTools , Lombok , Spring Batch ( ์ถํ ์ถ๊ฐ ์์ )
Spring Batch Library
@EnableBatchProcessing
์คํ๋ง ๋ฐฐ์น ์ด๊ธฐํ ์ค์ Class | ๊ธฐ๋ฅ ๋ฐ ์ค๋ช |
---|---|
BatchAutoConfiguration | 1. ์คํ๋ง ๋ฐฐ์น๊ฐ ์ด๊ธฐํ ๋ ๋ ์๋์ผ๋ก ์คํ๋๋ ์ค์ ํด๋์ค |
2. Job์ ์ํํ๋ JobLauncherApplicationRunner Bean์ ์์ฑ | |
SimpleBatchConfiguration | 1. JobBuilderFactory ์ StepBuilderFactory ์์ฑ |
2. ์คํ๋ง ๋ฐฐ์น์ ์ฃผ์ ๊ตฌ์ฑ ์์ ์์ฑ - ํ๋ก์ ๊ฐ์ฒด๋ก ์์ฑ๋จ | |
BatchConfigurerConfiguration | - BasicBatchConfigure |
1. SimpleBatchConfiguration ์์ ์์ฑํ ํ๋ก์ ๊ฐ์ฒด์ ์ค์ ๋์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ์ค์ ํด๋์ค | |
2. ๋น์ผ๋ก ์์กด์ฑ ์ฃผ์ ๋ฐ์์ ์ฃผ์ ๊ฐ์ฒด๋ค์ ์ฐธ์กฐํด์ ์ฌ์ฉ | |
- JpaBatchConfigurer | |
JPA ๊ด๋ จ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ์ค์ ํด๋์ค | |
์ฌ์ฉ์ ์ ์ BatchConfigurer ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ์ฌ ์ฌ์ฉ ํ ์ ์์ ! | |
proxy ๊ฐ์ฒด
: ์ค์ ๊ฐ์ฒด๊ฐ ์๋, ์ค์ ๊ฐ์ฒด์ ๋๋ฆฌ ์ญํ ์ ํ๋ ํด๋์ค
์คํ ์์
@EnableBatchProcessing
SimpleBatchConfiguration
BatchConfigurerConfiguration
BasicBatchConfigurer
JPABatchConfigurerBatchAutoConfiguration
๋ฐฐ์น ์ด๊ธฐํ Test
ํ ์คํธ ์ h2database ( ๋ฉ๋ชจ๋ฆฌ DB ) ๋ฅผ ์์กด์ฑ์ ์ถ๊ฐํ๋ค.
Spring Batch ์ ๊ฒฝ์ฐ ์คํค๋ง๊ฐ ์์ฑ ๋์ง ์์ผ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ DB๋ฅผ ์์ฑํด ๋์ด์ผ ์ค๋ฅ๊ฐ ๋์ง ์์
์ด ํ ์๋จ์ ์ง์ ๋ Class๋ค์ ์ค๋จ์ ์ ๊ฑธ์ด Class์ Flow๋ฅผ ํ์ธํด๋ณธ๋ค !
Sample Code
@RequiredArgsConstructor
@Configuration
public class HelloJobConfiguration {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
@Bean
public Job helloJob() {
return this.jobBuilderFactory.get("helloJob")
.start(helloStep1())
.next(helloStep2())
.build();
}
@Bean
public Step helloStep1() {
return stepBuilderFactory.get("helloStep1")
.tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
System.out.println(" ============================");
System.out.println(" >> Hello Spring Batch");
System.out.println(" ============================");
return RepeatStatus.FINISHED;
}
})
.build();
}
}
Batch Job ์์ฑ ์ฃผ์ Keywords
@Configuration
: ํ๋์ ๋ฐฐ์น Job์ ์ ์ํ๊ณ Bean ์ค์ JobBuilderFactory
: Job์ ์์ฑํ๋ ๋น๋ ํฉํ ๋ฆฌ ( ํธ์ ์ ๊ณต ์ ํธ ํด๋์ค )@Bean public Job helloJob() { return this.jobBuilderFactory.get("helloJob") //Job ์์ฑ .start(helloStep1()) // Step์ Job์ Start์ ์ธ์๋ก ์ฌ์ฉ๋จ .next(helloStep2()) // ๋ค์ Step์ ์งํ .build(); }
StepBuilderFactory
: Step์ ์์ฑํ๋ ๋น๋ ํฉํ ๋ฆฌ ( ํธ์ ์ ๊ณต ์ ํธ ํด๋์ค )@Bean public Step helloStep1() { return stepBuilderFactory.get("helloStep1") //Step ์์ฑ .tasklet(new Tasklet() { @Override public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { System.out.println(" ============================"); System.out.println(" >> Hello Spring Batch"); System.out.println(" ============================"); return RepeatStatus.FINISHED; } }) .build(); }
Job
: ์ฌ์ฉ์ ์ ์์ ์์
Step
: ์์
์ Steptasklet
: step ์์์ ๋จ์ผ ํ์คํฌ๋ก ์ํ๋๋ ๋ก์งreturn stepBuilderFactory.get("helloStep1") //Step ์์ฑ .tasklet(new Tasklet() { @Override public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { System.out.println(" ============================"); System.out.println(" >> Hello Spring Batch"); System.out.println(" ============================"); return RepeatStatus.FINISHED; } }) .build();
tasklet์ ์ต๋ช
Class RepeatStatus์ step์ ์์
์ ๋ฐ๋ณตํ๋๋ก ๋์ด์์ผ๋ฉฐ Return์ด null ์ธ ๊ฒฝ์ฐ 1ํ ์์ ํ ์ข
๋ฃํ๋ค.
์ด์ ๊ฐ์ ๊ธฐ๋ฅ์ผ๋ก์ RepeatStatus.FINISHED
๊ฐ ์๋ค.
RepeatStatus execute
์ ๋ฉ์๋ ์์๋ Step์ ์คํ ์ํฌ ๋ก์ง๊ตฌํ๋ถ๊ฐ ๋ค์ด๊ฐ์ผ ํ๋ค.
Job ๊ตฌ๋ -> Job์ Step ์ํ -> Tasklet ์ํ
์ฐ์ตํ๊ธฐ )
์์กด์ฑ ์ฃผ์
: ์ํํธ์จ์ด ์์ง๋์ด๋ง์์ ์์กด์ฑ ์ฃผ์
(dependency injection)์ ํ๋์ ๊ฐ์ฒด๊ฐ ๋ค๋ฅธ ๊ฐ์ฒด์ ์์กด์ฑ์ ์ ๊ณตํ๋ ํ
ํฌ๋์ด๋ค. "์์กด์ฑ"์ ์๋ฅผ ๋ค์ด ์๋น์ค๋ก ์ฌ์ฉํ ์ ์๋ ๊ฐ์ฒด์ด๋ค. ํด๋ผ์ด์ธํธ๊ฐ ์ด๋ค ์๋น์ค๋ฅผ ์ฌ์ฉํ ๊ฒ์ธ์ง ์ง์ ํ๋ ๋์ , ํด๋ผ์ด์ธํธ์๊ฒ ๋ฌด์จ ์๋น์ค๋ฅผ ์ฌ์ฉํ ๊ฒ์ธ์ง๋ฅผ ๋งํด์ฃผ๋ ๊ฒ์ด๋ค. "์ฃผ์
"์ ์์กด์ฑ(์๋น์ค)์ ์ฌ์ฉํ๋ ค๋ ๊ฐ์ฒด(ํด๋ผ์ด์ธํธ)๋ก ์ ๋ฌํ๋ ๊ฒ์ ์๋ฏธํ๋ค. ์๋น์ค๋ ํด๋ผ์ด์ธํธ ์ํ์ ์ผ๋ถ์ด๋ค. ํด๋ผ์ด์ธํธ๊ฐ ์๋น์ค๋ฅผ ๊ตฌ์ถํ๊ฑฐ๋ ์ฐพ๋ ๊ฒ์ ํ์ฉํ๋ ๋์ ํด๋ผ์ด์ธํธ์๊ฒ ์๋น์ค๋ฅผ ์ ๋ฌํ๋ ๊ฒ์ด ํจํด์ ๊ธฐ๋ณธ ์๊ฑด์ด๋ค.
์์กด์ฑ ์ฃผ์ ์ ์๋๋ ๊ฐ์ฒด์ ์์ฑ๊ณผ ์ฌ์ฉ์ ๊ด์ฌ์ ๋ถ๋ฆฌํ๋ ๊ฒ์ด๋ค. ์ด๋ ๊ฐ๋ ์ฑ๊ณผ ์ฝ๋ ์ฌ์ฌ์ฉ์ ๋ํ์ค๋ค.
์์กด์ฑ ์ฃผ์ ์ ๊ด๋ฒ์ํ ์ญ์ ์ด ํ ํฌ๋์ ํ ํํ์ด๋ค. ์ด๋ค ์๋น์ค๋ฅผ ํธ์ถํ๋ ค๋ ํด๋ผ์ด์ธํธ๋ ๊ทธ ์๋น์ค๊ฐ ์ด๋ป๊ฒ ๊ตฌ์ฑ๋์๋์ง ์์ง ๋ชปํด์ผ ํ๋ค. ํด๋ผ์ด์ธํธ๋ ๋์ ์๋น์ค ์ ๊ณต์ ๋ํ ์ฑ ์์ ์ธ๋ถ ์ฝ๋(์ฃผ์ ์)๋ก ์์ํ๋ค. ํด๋ผ์ด์ธํธ๋ ์ฃผ์ ์ ์ฝ๋๋ฅผ ํธ์ถํ ์ ์๋ค. ๊ทธ ๋ค์, ์ฃผ์ ์๋ ์ด๋ฏธ ์กด์ฌํ๊ฑฐ๋ ์ฃผ์ ์์ ์ํด ๊ตฌ์ฑ๋์์ ์๋น์ค๋ฅผ ํด๋ผ์ด์ธํธ๋ก ์ฃผ์ (์ ๋ฌ)ํ๋ค. ๊ทธ๋ฆฌ๊ณ ๋์ ํด๋ผ์ด์ธํธ๋ ์๋น์ค๋ฅผ ์ฌ์ฉํ๋ค. ์ด๋ ํด๋ผ์ด์ธํธ๊ฐ ์ฃผ์ ์์ ์๋น์ค ๊ตฌ์ฑ ๋ฐฉ์ ๋๋ ์ฌ์ฉ์ค์ธ ์ค์ ์๋น์ค์ ๋ํด ์ ํ์๊ฐ ์์์ ์๋ฏธํ๋ค. ํด๋ผ์ด์ธํธ๋ ์๋น์ค์ ์ฌ์ฉ ๋ฐฉ์์ ์ ์ํ๊ณ ์๋ ์๋น์ค์ ๊ณ ์ ํ ์ธํฐํ์ด์ค์ ๋ํด์๋ง ์๋ฉด ๋๋ค. ์ด๊ฒ์ "๊ตฌ์ฑ"์ ์ฑ ์์ผ๋ก๋ถํฐ "์ฌ์ฉ"์ ์ฑ ์์ ๊ตฌ๋ถํ๋ค.
์์กด์ฑ ์ฃผ์
์ฐธ์กฐ ( DI ๊ด๋ จ POST ) https://mangkyu.tistory.com/150
@RequiredArgsConstructor
: ์์ฑ์๋ฅผ ๋ณ๋๋ก ์์ฑํ์ฌ ๋ง๋ค์ง ์๊ณ , ๊ฐ์ฒด ์ธ์๋ฅผ ์ ์ธํ์ฌ ์์กด์ฑ ์ฃผ์
์ด ๋๋๋ก ํ๋ Lombok์ Annotation
@RequiredArgsConstructor
๋ฅผ ์ฌ์ฉํ ๋์๋ final ์ด๋ผ๋ keyword๋ฅผ ์ฌ์ฉ
final ์ฌ์ฉ ์ด์
final - ๊ฐ์ฒด๊ฐ ์์ฑ๋์ด ์ด ํ๋์ ์ฃผ์ ๋๋ฉด ๊ณ์ ๊ทธ๊ฒ๋ง ์ฐ์ด๋ฉด ๋๊ณ , ๊ตณ์ด ๋ค์ ์ฌํ ๋น ๋ ์ด์ /ํ์๋ ์๊ณ ๊ทธ๋ด ์ผ๋ ์์ -> ๊ตณ์ด (์์คํ ์ ์ผ๋ก) ์ฌํ ๋น ์์ฒด๋ ๊ฐ๋ฅํจ์ ์ด์ด๋ ํ์๊ฐ ์์ผ๋ฏ๋ก final ์ค์
Batch Job ์คํ ์ฑ๊ณต ~