首页 文章

Spring Batch基于JobParameters为单个JOB配置多个读取器/处理器/写入器

提问于
浏览
0

我有一个 spring 批量应用程序配置如下链接 .

https://spring.io/guides/gs/batch-processing/

现在我必须以这样的方式配置 step ,如果用户输入是文件则必须采用FlatFileItemReader,如果输入是SQL,则必须采用JdbcPagingItemReader . 我会将输入(文件/ sql)作为JobParameters传递 .

根据我的理解,spring的上述示例中的所有内容都是单例bean,它们在应用程序启动时加载到ApplicationContext中 . 由于 step 只能使用一个Reader配置一次 . 如何根据用户输入配置它以使用不同的Reader

如果只是读者正在改变,我不喜欢创建多个工作 .

我想过使用Factory / Strategy模式,但只有当 Step 不是bean时才能实现 . 这里所有这些都是在应用程序启动期间加载的bean .

无论模式如何,基于 JobParametersstep 中使用不同 Readers 的解决方案都会有所帮助 .

2 回答

  • 2

    你对 beans 子的看法是正确的 .

    如果您只有两种口味,最快的解决方案就是创建两个作业 . 但是,让我们忽视现实并谈论理论:

    您可以创建两个步骤,每个步骤一个,并使用 JobExecutionDecider 执行一个或另一个步骤(请参阅docs) .

    或者你创建自己的 ItemReader 并让它动态创建一个委托阅读器 . 如果使用 ItemStreamSupportAbstractItemCountingItemStreamItemReader 作为基类,则会得到 open(ExecutionContext executionContext) 方法 .

    示例代码:

    public class TicTacReader extends ItemStreamSupport implements ItemReader<TicTac>{
    
      protected ItemReader<TypedFieldSet<RecordType>> delegate;
    
      public TicTacReader() {
        super();
        setName(TicTacReader.class.getName());
      }
    
      @Override
      public void open(ExecutionContext executionContext) throws ItemStreamException {
        super.open(executionContext);
        // TODO: use the appropriate reader
        this.delegate = new VoodooReader();
      }
    
          @Override
      public TicTac read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
        TypedFieldSet<RecordType> line = this.delegate.read();
        // TODO ...
     }
    }
    
  • 1

    您可以使用@StepScope实现此功能 . 将您的bean名称,即FlatFileItemReader /或SQL放在作业参数中,然后使用下面的代码

    样本实施

    java config way

    @StepScope
            public Step step(@Value("#{jobParameters['beanId']}") final String beanId) {
            return stepBuilderFactory.get("step")
                    .<POJO, POJO> chunk(10000)
                    .reader(getReader(beanId))
                    .processor(Processor)
                    .writer(Writer)             
                    .build();
         }
    
    
     getReader(String beanId)
         {
            return applicationContext.getBean(beanId);
         }
    

    XML

    <batch:chunk reader="#{jobParameters['beanId']}" writer="writer" processor="processor" commit-interval="100" />
    

相关问题