【问题标题】:How to apply something like @Lazy to Spring Batch?如何将 @Lazy 之类的东西应用于 Spring Batch?
【发布时间】:2020-02-22 05:01:53
【问题描述】:

我有一个包含多个作业(作业 A、作业 B、作业 C、...)的 Spring Batch 项目。当我运行特定的作业 A 时,我得到作业 A 的日志,显示作业 B、C、...的所有 bean 也已创建。有什么办法可以避免在作业 A 启动时创建其他 bean。

我尝试使用@Lazy 注释,但它似乎不起作用。

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Autowired
    @Qualifier("springDataSource")
    public DataSource springDataSource;

    @Autowired
    @Qualifier("batchJobDataSource")
    public DataSource batchJobDataSource;

}


@Configuration
@PropertySource("classpath:partner.properties")
public class B extends BatchConfiguration {


    @Value("${partnerId}")
    private String partnerId;

    @Lazy
    @Bean
    public Job ProcessB(JobCompletionNotificationListener listener) {
      return jobBuilderFactory
        .get("ProcessB")
        .incrementer(new RunIdIncrementer())
        .listener(listener)
        .start(ProcessStepB())
        .build();
    }

    @Lazy
    @Bean
    public Step (ProcessStepB() {
        return stepBuilderFactory
                .get("(ProcessStepB")
                .<PartnerDTO, PartnerDTO> chunk(1)
                .reader(getPartner())
                .processor(process())
                .writer(save())
                .build();
    }

    @Lazy
    @Bean(destroyMethod = "")
    public Reader getPartner() {    
        return new Reader(batchJobDataSource,partnerId);
    }

    @Lazy
    @Bean
    public Processor process() {
        return new Processor();
    }

    @Lazy
    @Bean
    HistoryWriter historyWriter() {
        return new HistoryWriter(batchJobDataSource);
    }

    @Lazy
    @Bean
    UpdateWriter updateWriter() {
        return new UpdateWriter(batchJobDataSource);
    }

    @Lazy
    @Bean
    public CompositeItemWriter<PartnerDTO> saveTransaction() {
        List<ItemWriter<? super PartnerDTO>> delegates = new ArrayList<>();
        delegates.add(updateWriter());
        delegates.add(historyWriter());
        CompositeItemWriter<PartnerDTO> itemWriter = new CompositeItemWriter<>();
        itemWriter.setDelegates(delegates);
        return itemWriter;
    }
}

我还将@Lazy 放在@Configuration 上,但它也可以工作。

【问题讨论】:

  • 其他job的bean都被急切创建有什么问题?
  • 如果我的 Batch 有多个作业(例如:20 个作业,bean 的数量约为 100)。当我使用 Spring Cloud Data Flow 在我的 Batch 中开始特定工作时。它执行 java - jar 并加载所有 bean,包括不用于该作业的 bean。而且我认为这会影响每 1 个工作启动加载所有 bean 的时间。

标签: spring-batch


【解决方案1】:

这应该不是问题。但这里有一些想法可以尝试:

  • 使用 Spring 配置文件隔离作业 bean
  • 如果您使用 Spring Boot 2.2+,请尝试激活lazy bean initialization mode
  • 将每个作业打包在自己的 jar 中。这是 IMO 的最佳选择。

【讨论】:

  • 感谢您的建议。我会尝试第二个选项。但是,我不知道您的第一个解决方案。你能给我一些指南或文件吗?关于将每个工作包装在自己的罐子中,这意味着如果我有 100 个工作(实际上,在我的情况下这个数字可能更大)那么我需要 100 个罐子?这让我混淆了 Spring Cloud Data Flow 中 --spring.batch.job.names 的用途。
  • 对于 Spring 配置文件功能,请看这里:docs.spring.io/spring/docs/current/spring-framework-reference/…。您可以为每个作业定义一个配置文件以仅加载该作业的 bean。对于每个作业打包模型的罐子,是的,您将拥有与作业一样多的罐子。这真的不是问题:每个作业都有自己的生命周期(如果您修复作业中的错误,则无需重新部署所有这些),日志将按设计分开,bean 将按设计分开(例如您的实际问题),以及让一件事做好一件事的所有优势。
  • 使用惰性可能会受到影响。因为不是所有的bean都在第一次初始化但是当应用程序启动时,有bean被调用?我不知道哪个部分对此负责(在应用程序启动后称为 bean 作业?)。但是,我很困惑,如果我不将我的阅读器、处理器和编写器定义为 Bean,会发生什么?我的工作有什么问题吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-28
  • 1970-01-01
相关资源
最近更新 更多