✨ 회사에 입사하고 제일 많이 하는 일, 그리고 내가 해야 하는 제일 중요한 일은 데이터를 업데이트 하는 일이다. 스크립트를 이용해 aws 버킷에 있는 데이터들을 가공하고, 스프링 배치를 통해 실행한다. 이 과정을 처음 해보면서 bean과 jobScope의 개념을 조금 더 명확하게 이해할 필요가 있음을 느꼈다.
🪡 Bean
자바가 객체 지향 언어라는 것은 누구나 알고 있는 사실이다. bean은 그것에서 좀 더 들어가서, 스프링 컨테이너에 의해 관리되는 것이라고 볼 수 있다. 스프링 컨테이너에 의해서 관리가 되기 때문에 객체를 사용하거나 불러올 때, new 를 이용해서 초기화나 삭제할 필요가 없고, 동일한 역할의 인스턴스를 사용할 경우에 계속 사용하기 때문에 여러 곳에서 동시에 사용할 수 있다. 효율성이 높기 때문에 재사용성이 높은 것들에게 bean을 사용한다. 또한, 컨테이너 생성 시점에 컴포넌트에 대한 스캔을 하면서 빈으로 등록되기 때문에 동작을 수행할 때 생성되는 객체들과는 분명히 차이가 있다.
Spring batch에서 Bean을 사용하는 이유는 여러가지가 있지만, 사용자가 job을 호출하려고 하는 시점에 이미 객체가 만들어져있어야 한다는 점이 크다. 사용자가 프로젝트를 실행할 때
val jobExecution = jobLauncher.run(jobName, jobParameters)
이러한 형태로 넘기게 되는데, 스프링부트는 이것을 기존에 있는 bean 목록에서 스캔하고 찾아가 실행을 한다. 그렇기 때문에 컨테이너가 된 이후, 작업이 시작되기 전 시점에 이미 생성이 되어 있어야 하고, 배치를 한번이 아니라 여러번 돌리거나 다른 곳에서 사용할 수 있도록 재사용성 또한 높아야 한다.
🧶 JobScope
위에서 bean의 생성 시점은 컨테이너가 생성된 후라고 했다. 그러나 모든 bean이 해당 지점에 생성이 된다면 부하는 말도 안 되게 커질 것이다. 이와 같이 불필요한 메모리 사용을 줄이고, 불필요한 Bean을 사전 생성하지 않기 위해 JobScope가 존재한다. 이 어노테이션은 bean이 job 실행 시점에 생성되고, job이 끝나는 시점에 삭제됨을 명시하는 어노테이션이다. 주로 job 내의 step에서 활용을 하는데, job이 실행됨과 함께 해당 어노테이션에 속한 Bean이 생성되고, job이 종료되는 시점에 삭제된다.
@Bean
fun newJob() = batch {
job("newJob") {
incrementer(RunIdIncrementer())
listener(jobExecutionListener())
step(clearStep())
}
}
@Bean
@JobScope
fun clearStep() = batch {
step("clearStep"){
tasklet({ _, _ ->
jdbcTemplate.execute("TRUNCATE TABLE my_table")
RepeatStatus.FINISHED
}, transactionManager)
}
}
이런 식의 코드가 있으면, 어플리케이션을 최초 실행할 때 bean에 해당하는 newJob은 스프링 컨테이너가 생성된 이후 파라미터 스캔에 의해 먼저 등록이 되고, newJob을 실행하게 되면 그 밑에 있는 clearStep의 bean이 실행되는 것이다. 이 작업이 끝나면 clearStep 에 해당하는 bean 또한 삭제된다.
'JAVA&KOTLIN' 카테고리의 다른 글
[Spring Batch] S3 버킷 스트리밍 방식 vs 로컬 다운로드 방식 (0) | 2024.08.23 |
---|---|
[Spring Batch&Kotlin] WebFlux 를 쓰는 이유? 그리고 발견된 문제 (0) | 2024.08.05 |
VO? DTO? 둘의 차이가 뭔데 (0) | 2024.07.31 |