2

当我用 'scope=step' 定义一个 'MethodInvokingFactory' bean 时,我收到一个错误,即无法确定 bean 的类型。当我将 'scope=step' 替换为 'lazy-init=true' 时,它运行良好。据我所知,两者都用于bean的后期绑定,除了一个区别。这两种方式之间还有其他区别吗?另外,我的用法正确吗?

请让我知道您对此的看法。

4

3 回答 3

4

从低层次的角度回答你的问题:

lazy-init="true"意味着在创建上下文时 bean 不会被实例化,但会在它被其他 bean 引用时被创建。我认为这很清楚,也来自@AravindA 评论。

Scoped bean 以不同的方式工作。当上下文被创建时,这个 bean 被包装到额外的代理对象中(默认由 CGLIB 创建),它被传递给引用它的 bean(这个代理默认是单例的,例如共享的)。因此,每次在运行时在代理上调用方法时,Spring 都会与调用相交,请求工厂返回 bean 的实例并调用该 bean 上的方法。反过来,工厂可以在 HTTP 请求(“请求”范围)或 HTTP 会话(“会话”范围)中查找“真实”bean 实例和/或在必要时创建新实例。后期实例化允许使用“运行时”(范围)值初始化范围 bean,例如来自 HTTP 请求/会话的值,这些值在创建上下文时显然是未定义的。特别是“步” -scoped bean 绑定到线程本地(请记住,步骤并行运行以进行分区)。因此,当您在它们上调用方法时,作用域 bean 将被取消引用。最后,通过在作用域 bean 设置为另一个 bean(例如在 setter 中)之后调用任何方法,可以轻松打破这种优雅的 Spring“意识形态”:)

于 2012-01-06T16:42:18.373 回答
2
      One thing to understand about lazy-initialization is that even though a bean 
      definition may be marked up as being lazy-initialized, if the lazy-initialized     
      bean is the dependency of a singleton bean that is not lazy-initialized, when the
      ApplicationContext is eagerly pre-instantiating the singleton, it will have to 
      satisfy all of the singletons dependencies, one of which will be the 
      lazy-initialized bean!

      Using a scope of Step is required in order to use late binding since the bean 
      cannot actually be instantiated until the Step starts, which allows the   
      attributes to be found. Because it is not part of the Spring container by   
      default, the scope must be added explicitly, either by using the batch namespace 
      or by including a bean definition explicitly for the StepScope (but not both):

      <bean class="org.springframework.batch.core.scope.StepScope" />

阅读此处此处了解更多信息

scope="step" 与延迟初始化无关。它用于“步骤”内参数的后期绑定。

于 2012-01-06T07:26:56.453 回答
1

step 范围专门用于作业/步骤属性的后期绑定,而不是真正用于 bean 的后期绑定,这意味着 spring bean 上下文/工厂将增强 stepscoped bean 并查找要设置的属性,例如

value="#{jobParameters[input.file.name]}
于 2012-01-06T10:23:29.017 回答