ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스프링 배치 도메인 이해 -JobParameter
    Study/Spring Batch 2024. 2. 8. 08:20

    1) JobParameter

    기본 개념

    • Job을 실행할 때 함께 포함되어 사용되는 파라미터를 가진 도메인 객체
      • JobLauncher가 Job을 실행시킬 때 Job, Job parameter 두개의 인자를 받는다.
        Job paramter는 key, value로 구성되어진 map을 포함하고있다.
    • 하나의 Job에 존재할 수 있는 여러 개의 JobInstance를 구분하기 위한 용도
    • JobParameters와 JobInstance는 1:1 관계

     

    2) 생성 및 바인딩

    • 어플리케이션 실행 시 주입
      • java -jar springbatch.jar requestDate=20240207
    • 코드로 생성
      • JobParameterBuilder, DefaultJobParametersConverter
    • SpEL 이용 (Spring Expression Language)
      • @Value("#{jogParameter[requestDate]}"), @JobScope, @StepScope 선언 필수

     

    3) BATCH_JOB_EXECUTION_PARAM 테이블과 매핑

    JOB_EXECUTION 과 1:N의 관계

     

    실습

    실습 1) 코드로 생성

    자동 실행을 막기 위해 spring.batch.job.enable false로 설정 후 다음 코드를 실행시켜본다.

    @Component
    public class JobParameterTest implements ApplicationRunner { // 테스트를 하기 위해 수동으로 구성
    
        @Autowired
        JobLauncher jobLauncher; // Job을 실행시키는 JobLauncher class
    
        @Autowired
        Job job;
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
    
            JobParameters jobParameters = new JobParametersBuilder()
                    .addString("name", "user1")
                    .addLong("seq", 1L)
                    .addDate("date", new Date())
                    .addDouble("fee", 16.5)
                    .toJobParameters();
    
            jobLauncher.run(job, jobParameters);
        }
    }

    BATCH_JOB_EXECUTION_PARAM 테이블에 타입과 key value가 저장되었다.

    여기서 저장된 JobParameter의 값을 어디서 어떻게 참조할까?

    • StepContribution
      StepContribution > StepExecution > JobExecution > JobParameters
    • ChunkContext
      ChunkContext > StepContext > StepExecution > JobExecution > JobParameters
    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1") // Step의 이름을 부여
                .tasklet(new Tasklet() { // 구현해야할 내용을 Tasklet에 기술
                    @Override
                    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                        // JobParameter의 값을 어디서 어떻게 참조할까? StepContribution, ChunkContext 확인.
    
                        JobParameters jobParameters = contribution.getStepExecution().getJobExecution().getJobParameters();
                        jobParameters.getString("name");
                        jobParameters.getLong("seq");
                        jobParameters.getDate("date");
                        jobParameters.getDouble("fee");
    
                        // chunkContext.getStepContext().getStepExecution().getJobExecution().getJobParameters(); // 이건 위와 똑같은 방식이므로 패스
                        Map<String, Object> jobParametersMap = chunkContext.getStepContext().getJobParameters();
                        jobParametersMap.get("name");
    
                        System.out.println("step1 has executed");
                        return RepeatStatus.FINISHED; // 한 번 실행하고 종료.
                        // return RepeatStatus.CONTINUABLE; <= 계속 실행하고 싶으면...
                    }
                })
                .build();
    }

    디버깅으로 위 코드를 확인해보자.

    JobParameters 객체의 내용

    StepContext 클래스의 getJobParameters 메서드는 JobParameter를 Map으로 반환한다.

    /**
     * @return a map containing the items from the {@link JobParameters}
     */
    public Map<String, Object> getJobParameters() {
        Map<String, Object> result = new HashMap<>();
        for (Entry<String, JobParameter> entry : stepExecution.getJobParameters().getParameters().entrySet()) {
            result.put(entry.getKey(), entry.getValue().getValue());
        }
        return Collections.unmodifiableMap(result);
    }

    getJobParameters 메서드로 가져온 Map의 내용

     

    실습 2) 어플리케이션 실행 시 주입

    mvn package로 jar파일을 생성 후 어플리케이션을 실행하며 파라미터를 넘겨보자.

    spring.batch.job.enable 는 다시 true로 변경하거나 주석처리한다.

    spring:
      config:
        activate:
          on-profile: mysql
      datasource:
        hikari:
          jdbc-url: jdbc:mysql://localhost:3306/springbatch?useUnicode=true&characterEncoding=utf8
          username: root
          password: pass
          driver-class-name: com.mysql.jdbc.Driver
      batch:
        jdbc:
          initialize-schema: always
    #    job:
    #      enabled: false # 자동 실행을 막는다.

    mvn clean 후 package 실행하여 jar를 생성한다.

    % pwd
    /Users/kong/dev/workspace/spring-batch-study/target
    % java -jar spring-batch-lecture-0.0.1-SNAPSHOT.jar name=user1 seq(long)=1L date(date)=2024/01/01 fee(double)=16.5
    zsh: no matches found: seq(long)=1L
    % java -jar spring-batch-lecture-0.0.1-SNAPSHOT.jar 'name=user2' 'seq(long)=2L' 'date(date)=2024/01/01' 'fee(double)=16.5'

     

    zsh:no matches found 에러가 발생해서 각각의 파라미터를 따옴표로 감싸줬다.
    (여기서 전체 파라미터를 따옴표로 감싸면 하나의 string parameter로 인식하니 주의)

    파라미터 내용을 Run/Debug Configurations에서 넘겨서 실행할 수도 있다.

     

    댓글

Designed by Tistory.