Spring batch Spring批处理基于作业参数为单个作业配置多个读卡器/处理器/写入器

Spring batch Spring批处理基于作业参数为单个作业配置多个读卡器/处理器/写入器,spring-batch,spring-ioc,Spring Batch,Spring Ioc,我有一个spring批处理应用程序,配置如下链接 现在我必须配置步骤,如果用户输入是file,它必须使用FlatFileItemReader;如果用户输入是SQL,它必须使用JdbcPagingItemReader。我将输入(file/sql)作为JobParameters传递 据我所知,上面spring示例中的所有内容都是单例bean,在应用程序启动时加载到ApplicationContext中。 As步骤只能使用一个读卡器配置一次。我如何配置它以根据用户输入获取不同的读卡器 如果只有读者在

我有一个spring批处理应用程序,配置如下链接

现在我必须配置步骤,如果用户输入是file,它必须使用FlatFileItemReader;如果用户输入是SQL,它必须使用JdbcPagingItemReader。我将输入(file/sql)作为JobParameters传递

据我所知,上面spring示例中的所有内容都是单例bean,在应用程序启动时加载到ApplicationContext中。 As步骤只能使用一个读卡器配置一次。我如何配置它以根据用户输入获取不同的读卡器

如果只有读者在改变,我不喜欢创造多个工作岗位

我曾想过使用工厂/策略模式,但这只有在步骤不是bean时才能实现。在这里,它们都是在应用程序启动期间加载的bean


无论模式如何,基于作业参数步骤中使用不同读取器的解决方案都是有帮助的。

您关于bean的假设是正确的

如果你只有两种口味,最快的解决办法就是创造两份工作。但让我们忽略现实,谈谈理论:

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

或者,您可以创建自己的
ItemReader
,并让它动态创建一个委托读取器。如果使用
ItemStreamSupport
AbstractItemCountingItemStreamItemReader
作为基类,则会得到一个
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 ...
 }
}
公共类TicTacReader扩展ItemStreamSupport实现ItemReader{
受保护的ItemReader委托;
公共图书馆阅读器(){
超级();
setName(TicTacReader.class.getName());
}
@凌驾
public void open(ExecutionContext ExecutionContext)抛出ItemStreamException{
super.open(executionContext);
//TODO:使用适当的读取器
this.delegate=新伏都教阅读器();
}
@凌驾
public TicTac read()引发异常、UnexpectedInputException、ParseException、NontTransientResourceException{
TypedFieldSet行=this.delegate.read();
//待办事项。。。
}
}

你对豆子的推测是正确的

如果你只有两种口味,最快的解决办法就是创造两份工作。但让我们忽略现实,谈谈理论:

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

或者,您可以创建自己的
ItemReader
,并让它动态创建一个委托读取器。如果使用
ItemStreamSupport
AbstractItemCountingItemStreamItemReader
作为基类,则会得到一个
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 ...
 }
}
公共类TicTacReader扩展ItemStreamSupport实现ItemReader{
受保护的ItemReader委托;
公共图书馆阅读器(){
超级();
setName(TicTacReader.class.getName());
}
@凌驾
public void open(ExecutionContext ExecutionContext)抛出ItemStreamException{
super.open(executionContext);
//TODO:使用适当的读取器
this.delegate=新伏都教阅读器();
}
@凌驾
public TicTac read()引发异常、UnexpectedInputException、ParseException、NontTransientResourceException{
TypedFieldSet行=this.delegate.read();
//待办事项。。。
}
}

您可以使用@StepScope实现这一点。在作业参数中输入bean名称,即FlatFileItemReader/或SQL,然后使用下面的代码

示例实现

java配置方式

    @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);
     }
<batch:chunk reader="#{jobParameters['beanId']}" writer="writer" processor="processor" commit-interval="100" />
@StepScope
公共步骤步骤(@Value(“#{jobParameters['beanId']}”)最终字符串beanId){
返回stepBuilderFactory.get(“步骤”)
.chunk(10000)
.reader(getReader(beanId))
.处理器(处理器)
.作者(作者)
.build();
}
getReader(字符串beanId)
{
返回applicationContext.getBean(beanId);
}
XML

    @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);
     }
<batch:chunk reader="#{jobParameters['beanId']}" writer="writer" processor="processor" commit-interval="100" />

您可以使用@StepScope实现这一点。在作业参数中输入bean名称,即FlatFileItemReader/或SQL,然后使用下面的代码

示例实现

java配置方式

    @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);
     }
<batch:chunk reader="#{jobParameters['beanId']}" writer="writer" processor="processor" commit-interval="100" />
@StepScope
公共步骤步骤(@Value(“#{jobParameters['beanId']}”)最终字符串beanId){
返回stepBuilderFactory.get(“步骤”)
.chunk(10000)
.reader(getReader(beanId))
.处理器(处理器)
.作者(作者)
.build();
}
getReader(字符串beanId)
{
返回applicationContext.getBean(beanId);
}
XML

    @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);
     }
<batch:chunk reader="#{jobParameters['beanId']}" writer="writer" processor="processor" commit-interval="100" />

请记住,Spring配置(因此bean)可以根据Spring概要文件、环境变量、应用程序上下文bean的存在、属性等进行调整

  • @侧面图
  • @ConditionalOnBean@ConditionalOnMissingBean
  • @ConditionalOnClass@ConditionalOnMissingClass
  • @条件性下压(弹簧)
  • @ConditionalOnJava(JVM版本)
  • @阿隆隆迪
  • @ConditionalOnProperty
  • @ConditionalOnResource
  • @ConditionalOnWebApplication@ConditionalOnNotWebApplication
  • @ConditionalOnEnabledEndpoint(参见 执行器)

因此,您应该能够根据执行上下文筛选工厂(也可以通过@Configuration类和@Bean方法)。

请记住,Spring配置(因此Bean)可以根据Spring概要文件、环境变量和应用程序上下文Bean进行调整