Spring Batch后期绑定-步骤范围还是工作范围?

时间:2018-07-27 02:19:09

标签: spring-boot spring-batch

我正在使用Spring Batch处理一个项目。在这个项目中,我使用Spring Batch后期绑定,其中使用 JobParameters 注入了一个参数(将作为SQL读取器查询的条件的字符串)。目前,我正在使用@StepScope进行后期绑定,并且一切正常。

我要问的是何时使用@StepScope和何时使用@JobScope。我已经阅读了Spring Batch参考,并且在Google上搜索了StepScope和JobScope。我得到的只是:

a。 StepScope:Spring Batch将在每次执行步骤时使用spring容器实例化该组件的新实例。

b。 JobScope:每个执行的作业只有一个实例。

我只是无法确定何时使用StepScope或JobScope。有人可以进一步解释吗?

2 个答案:

答案 0 :(得分:0)

每个作业都由三个步骤组成,一个读取步骤,一个处理步骤和一个写入步骤。如果您创建具有Step作用域的bean,则可以从这三个步骤中的每个步骤中引用它-但是在每个步骤中您将获得该bean的不同实例。我创建了一个具有Job作用域的bean,然后可以从这三个步骤的每一个中引用它-并且在所有三个上下文中它都是相同的实例。

因此,如果您需要一步将某项内容存储在同一作业的后续步骤将访问的bean中,则希望该bean位于Job范围内。如果要确保任何步骤在bean中存储和操作的数据对于该步骤是本地的(对其他步骤都是隐藏的),则希望该bean在Step范围内。

答案 1 :(得分:0)

一个步骤由读取,转换/处理和写入阶段组成,后者是每个块,在整个处理阶段具有重试/回滚的复杂性,而读取阶段通常是无回滚的无重试。作业由任意多个步骤组成,每个步骤都可以根据需要进行。因此,对于每个读取/处理/写入阶段以及给定步骤的侦听器,步骤作用域bean都是相同的实例。作业范围是作业中所有步骤的同一实例。

因此,如果您需要在同一工作的多个步骤中使用相同的侦听器进行某些处理(您需要将数据转换为中间格式并进行验证,然后再将所有数据处理到数据库中,那么您需要相同的侦听器在某个地方执行一些异步审核过程),那么您将确定该侦听器的作用域并针对该工作中的两个步骤进行注册。这样,每个步骤都会看到代理后面的对象的相同实例,并且针对“读取错误”或“写入后”或“步骤后”之类的东西调用相同实例上的相同方法(取决于您是否重新使用基于注释的侦听器或基于接口的侦听器以及您正在侦听的内容

例如,

您的阅读器在任何时候都只能被一个步骤使用,因此,将诸如阅读器之类的内容作为步骤范围通常是正确的,即创建该阅读器并指向特定资源。一个更好的例子是一个侦听器,您可能需要在一个步骤完成后清理目录或执行某些操作,但是由于此过程随每个步骤而改变(目录的位置),尽管您希望侦听器使用相同的实际对象类型,并且您甚至可能希望它执行相同的操作,希望它使用新目录和新的UUID前缀或每步执行一些操作,您可能会使用相同的Job参数为该bean定义一个,但是定义会是新的临时目录或UUID等,然后将该bean定义设置为Step作用域,以便在将其连接到两个不同的步骤时,它们在惰性代理后面得到两个不同的实际对象。

现在,作业监听器可能应该是作业范围的,但是这里提出了一个问题,如果您想在所有步骤中使用相同的实例,那么您将使用“常规范围”单例,改用它。

  • 在工作之外,您看不到工作范围或步骤范围
  • 在步骤之外,您看不到步骤范围

  • 在步骤中,您可以看到作业和步骤范围豆
  • 在作业内,您可以看到所有作业范围Bean或单例

还要考虑:

创建单例并将其连接到作业作用域或步骤作用域bean中时,即使您的单例是“ everywhere”使用的同一对象,当它引用内部的作业或步骤作用域对象时(实际上是一个代理),则每个工作或步骤都会看到不同的内容。 因此,您可以使用一个Singleton Bean来代表您的步骤,并且该步骤可以引用步骤作用域的Bean。这样,您的Step实例就可以并可能只是一个单例来构建Job,但它已将其在执行时所依赖的步骤范围的bean与它的bean方法/定义/构造函数关联在一起实例。