Question

When I defined a 'MethodInvokingFactory' bean with 'scope=step', I got an error that the type of the bean can't be determined. It worked fine when I replaced 'scope=step' with 'lazy-init=true'. As per my knowledge, both are used for the late binding of the beans, except for that one difference. Are there any other differences between these two ways? Also, is my usage correct?

Please let me know your thoughts about this.

Was it helpful?

Solution

To answer to your question from low-level perspective:

lazy-init="true" means that bean will not be instantiated when the context is created, but will be created when it is referred e.g. by another bean. I think this is clear, also from @AravindA comment.

Scoped bean works in different manner. When context is created this bean is wrapped into additional proxy object (by default created by CGLIB), which is passed to the bean that refers it (this proxy is by default singleton, e.g. shared). So each time the method is invoked on the proxy in runtime Spring intersects the call, requests the factory to return the instance of the bean and invokes the method on that bean. The factory in its turn may lookup for "real" bean instance e.g. in HTTP request ("request" scope) or HTTP session ("session" scope) and/or create new instance if necessary. Late instantiation allows to initialize the scoped bean with "runtime" (scope) values, e.g. values from HTTP request/session which are obviously undefined when context was created. In particular "step"-scoped beans are bound to thread local (remember that steps are run in parallel for partitioning). So, scoped beans are dereferred when you call a method on them. Finally one can easily break this elegant Spring "ideology" by calling any method on scoped bean just after it is set to another bean (e.g. in the setter) :)

OTHER TIPS

      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" />

Read here and here for more info

The scope="step" has nothing to do with Lazy initialization . It is use for late binding of parameters inside a "Step" .

the step scope is specifically for latebinding of job/step attributes and not really for late-binding of beans, meaning the spring bean context/factory will enhance stepscoped beans and look for attributes to set, e.g.

value="#{jobParameters[input.file.name]}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top