2011-11-14 21 views
18

Tôi có một yêu cầu trong đó một tasklet, lưu trữ tất cả các tệp trong các thư mục trong một arraylist. Kích thước của danh sách được lưu trữ trong ngữ cảnh thực hiện công việc. Sau đó, số này được truy cập từ một tasklet khác trong một bước khác. Làm thế nào để làm điều này. Tôi cố gắng để lưu trữ trong bối cảnh jobexecution, khi chạy ném ngoại lệ thu unmodifiable,Lưu trữ trong JobExecutionContext từ tasklet và truy cập trong một tasklet khác

public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) 
throws Exception { 
    StepContext stepContext = arg1.getStepContext(); 
    StepExecution stepExecution = stepContext.getStepExecution(); 
    JobExecution jobExecution = stepExecution.getJobExecution(); 
    ExecutionContext jobContext = jobExecution.getExecutionContext(); 
    jobContext.put("FILE_COUNT",150000); 

cũng lưu trữ các tài liệu tham khảo stepexection trong beforestep chú thích .still không possioble.kindly cho tôi biết, làm thế nào để chia sẻ dữ liệu giữa hai tasklets.

Trả lời

43

bạn có ít nhất 4 khả năng:

  1. sử dụng ExecutionPromotionListener để pass data to future steps
  2. sử dụng một (mùa xuân) đậu để chứa dữ liệu liên bước, ví dụ một ConcurrentHashMap
    • mà không cần thêm hành động dữ liệu này sẽ không thể truy cập cho một tái khởi động
  3. truy cập JobExecutionContext trong tasklet của bạn, nên được sử dụng một cách thận trọng, sẽ gây ra vấn đề chủ đề cho các bước song song
  4. sử dụng mới jobscope (giới thiệu với mùa xuân đợt 3)

Mã số Ví dụ để truy cập JobExecution từ Tasklet:

  1. thiết lập một giá trị

    public class ChangingJobExecutionContextTasklet implements Tasklet { 
    
        /** {@inheritDoc} */ 
        @Override 
        public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { 
         // set variable in JobExecutionContext 
         chunkContext 
           .getStepContext() 
           .getStepExecution() 
           .getJobExecution() 
           .getExecutionContext() 
           .put("value", "foo"); 
    
         // exit the step 
         return RepeatStatus.FINISHED; 
        } 
    
    } 
    
  2. chiết xuất một giá trị

    public class ReadingJobExecutionContextTasklet implements Tasklet { 
    
        private static final Logger LOG = LoggerFactory.getLogger(ChangingJobExecutionContextTasklet.class); 
    
        /** {@inheritDoc} */ 
        @Override 
        public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { 
         // pull variable from JobExecutionContext 
         String value = (String) chunkContext 
                .getStepContext() 
                .getStepExecution() 
                .getJobExecution() 
                .getExecutionContext() 
                .get("value"); 
    
         LOG.debug("Found value in JobExecutionContext:" + value); 
    
         // exit the step 
         return RepeatStatus.FINISHED; 
        } 
    } 
    

tôi tạo ra các ví dụ mã trong 3 giải pháp đầu tiên trong my spring-batch-examples github repository, thấy mô-đun phức tạp và gói interstepcommunication

+0

cảm ơn tôi sẽ xem xét điều này. tôi muốn một giá trị trong jobexecutioncontext được trích xuất từ ​​bean JobExecutionDecider –

+0

@MichaelLange: Tại sao mã Suresh gốc lại ném một ngoại lệ? Có vẻ ngữ nghĩa giống như đoạn mã bạn đã cung cấp. –

+0

nó cũng nên làm việc, tôi chỉ đoán ông đã sử dụng 'chunkContext.getStepContext(). GetJobExecutionContext(). Put (...)' trước, điều này sẽ ném ngoại lệ unmodifiable –

4

Cách khác là sử dụng StepExecutionListener được gọi sau khi thực hiện bước. Tasklet của bạn có thể triển khai và chia sẻ thuộc tính cục bộ.

public class ReadingJobExecutionContextTasklet implements Tasklet, StepExecutionListener { 
    private String value; 

    @Override 
    public ExitStatus afterStep(StepExecution stepExecution) { 
     ExecutionContext jobExecutionContext = stepExecution.getJobExecution().getExecutionContext(); 

     jobExecutionContext.put("key", value); 
     //Return null to leave the old value unchanged. 
     return null; 
    } 
} 

Vì vậy, trong bước, bean của bạn là một tasklet và một người nghe như dưới đây. Bạn cũng nên định cấu hình phạm vi bạn bước thành "bước":

<batch:step id="myStep" next="importFileStep"> 
     <batch:tasklet> 
      <ref bean="myTasklet"/> 
      <batch:listeners> 
       <batch:listener ref="myTasklet"/> 
      </batch:listeners> 
     </batch:tasklet> 
    </batch:step> 

    <bean id="myTasklet" class="ReadingJobExecutionContextTasklet" scope="step"> 
Các vấn đề liên quan