Skip to content

Commit dde5455

Browse files
committed
Update step injection style in flow examples
Resolves #4460
1 parent a1b1ede commit dde5455

File tree

1 file changed

+66
-51
lines changed

1 file changed

+66
-51
lines changed

Diff for: spring-batch-docs/modules/ROOT/pages/step/controlling-flow.adoc

+66-51
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,21 @@ necessarily mean that the `Job` should fail. Furthermore, there may be more than
77
of "`success`" that determines which `Step` should be executed next. Depending upon how a
88
group of `Steps` is configured, certain steps may not even be processed at all.
99

10+
[IMPORTANT]
11+
.Step bean method proxying in flow definitions
12+
====
13+
A step instance must be unique within a flow definition. When a step has multiple outcomes in a flow definition,
14+
it is important that the same instance of the step is passed to the flow definition methods (`start`, `from`, etc).
15+
Otherwise, the flow execution might behave unexpectedly.
16+
17+
In the following examples, steps are injected as parameters to the flow or job bean definition methods. This dependency injection style guarantees the uniqueness of steps in the flow definition.
18+
However, if the flow is defined by calling step definition methods annotated with `@Bean`, then steps might not be unique if bean method proxying is disabled (ie `@Configuration(proxyBeanMethods = false)`).
19+
If the inter-bean injection style is preferred, then bean method proxying must be enabled.
20+
21+
Please refer to the https://docs.spring.io/spring-framework/reference/core/beans/java/configuration-annotation.html[Using the @Configuration annotation]
22+
section for more details about bean method proxying in Spring Framework.
23+
====
24+
1025
[[SequentialFlow]]
1126
== Sequential Flow
1227

@@ -29,11 +44,11 @@ The following example shows how to use the `next()` method in Java:
2944
[source, java]
3045
----
3146
@Bean
32-
public Job job(JobRepository jobRepository) {
47+
public Job job(JobRepository jobRepository, Step stepA, Step stepB, Step stepC) {
3348
return new JobBuilder("job", jobRepository)
34-
.start(stepA())
35-
.next(stepB())
36-
.next(stepC())
49+
.start(stepA)
50+
.next(stepB)
51+
.next(stepC)
3752
.build();
3853
}
3954
----
@@ -95,11 +110,11 @@ proceed to either of two different steps (`stepB` or `stepC`), depending on whet
95110
[source, java]
96111
----
97112
@Bean
98-
public Job job(JobRepository jobRepository) {
113+
public Job job(JobRepository jobRepository, Step stepA, Step stepB, Step stepC) {
99114
return new JobBuilder("job", jobRepository)
100-
.start(stepA())
101-
.on("*").to(stepB())
102-
.from(stepA()).on("FAILED").to(stepC())
115+
.start(stepA)
116+
.on("*").to(stepB)
117+
.from(stepA).on("FAILED").to(stepC)
103118
.end()
104119
.build();
105120
}
@@ -185,7 +200,7 @@ The following example contains the `on` element when using Java Configuration:
185200
[source, java]
186201
----
187202
...
188-
.from(stepA()).on("FAILED").to(stepB())
203+
.from(stepA).on("FAILED").to(stepB)
189204
...
190205
----
191206
@@ -239,11 +254,11 @@ The following example shows how to work with a different exit code in Java:
239254
[source, java]
240255
----
241256
@Bean
242-
public Job job(JobRepository jobRepository) {
257+
public Job job(JobRepository jobRepository, Step step1, Step step2, Step errorPrint1) {
243258
return new JobBuilder("job", jobRepository)
244-
.start(step1()).on("FAILED").end()
245-
.from(step1()).on("COMPLETED WITH SKIPS").to(errorPrint1())
246-
.from(step1()).on("*").to(step2())
259+
.start(step1).on("FAILED").end()
260+
.from(step1).on("COMPLETED WITH SKIPS").to(errorPrint1)
261+
.from(step1).on("*").to(step2)
247262
.end()
248263
.build();
249264
}
@@ -319,9 +334,9 @@ In the following Java example, after the `step` executes, the `Job` ends:
319334
[source, java]
320335
----
321336
@Bean
322-
public Job job(JobRepository jobRepository) {
337+
public Job job(JobRepository jobRepository, Step step1) {
323338
return new JobBuilder("job", jobRepository)
324-
.start(step1())
339+
.start(step1)
325340
.build();
326341
}
327342
----
@@ -332,7 +347,7 @@ In the following XML example, after the `step` executes, the `Job` ends:
332347
+
333348
[source, xml]
334349
----
335-
<step id="stepC" parent="s3"/>
350+
<step id="step1" parent="s3"/>
336351
----
337352
338353
====
@@ -395,12 +410,12 @@ The following example shows the scenario in Java:
395410
[source, java]
396411
----
397412
@Bean
398-
public Job job(JobRepository jobRepository) {
413+
public Job job(JobRepository jobRepository, Step step1, Step step2, Step step3) {
399414
return new JobBuilder("job", jobRepository)
400-
.start(step1())
401-
.next(step2())
415+
.start(step1)
416+
.next(step2)
402417
.on("FAILED").end()
403-
.from(step2()).on("*").to(step3())
418+
.from(step2).on("*").to(step3)
404419
.end()
405420
.build();
406421
}
@@ -455,11 +470,11 @@ The following example shows the scenario in Java:
455470
[source, java]
456471
----
457472
@Bean
458-
public Job job(JobRepository jobRepository) {
473+
public Job job(JobRepository jobRepository, Step step1, Step step2, Step step3) {
459474
return new JobBuilder("job", jobRepository)
460-
.start(step1())
461-
.next(step2()).on("FAILED").fail()
462-
.from(step2()).on("*").to(step3())
475+
.start(step1)
476+
.next(step2).on("FAILED").fail()
477+
.from(step2).on("*").to(step3)
463478
.end()
464479
.build();
465480
}
@@ -517,9 +532,9 @@ The following example shows the scenario in Java:
517532
[source, java]
518533
----
519534
@Bean
520-
public Job job(JobRepository jobRepository) {
535+
public Job job(JobRepository jobRepository, Step step1, Step step2) {
521536
return new JobBuilder("job", jobRepository)
522-
.start(step1()).on("COMPLETED").stopAndRestart(step2())
537+
.start(step1).on("COMPLETED").stopAndRestart(step2)
523538
.end()
524539
.build();
525540
}
@@ -575,11 +590,11 @@ directly to the `next` call when using Java configuration:
575590
[source, java]
576591
----
577592
@Bean
578-
public Job job(JobRepository jobRepository) {
593+
public Job job(JobRepository jobRepository, MyDecider decider, Step step1, Step step2, Step step3) {
579594
return new JobBuilder("job", jobRepository)
580-
.start(step1())
581-
.next(decider()).on("FAILED").to(step2())
582-
.from(decider()).on("COMPLETED").to(step3())
595+
.start(step1)
596+
.next(decider).on("FAILED").to(step2)
597+
.from(decider).on("COMPLETED").to(step3)
583598
.end()
584599
.build();
585600
}
@@ -633,27 +648,27 @@ previously discussed transition elements, such as the `next` attribute or the `n
633648
[source, java]
634649
----
635650
@Bean
636-
public Flow flow1() {
651+
public Flow flow1(Step step1, Step step2) {
637652
return new FlowBuilder<SimpleFlow>("flow1")
638-
.start(step1())
639-
.next(step2())
653+
.start(step1)
654+
.next(step2)
640655
.build();
641656
}
642657
643658
@Bean
644-
public Flow flow2() {
659+
public Flow flow2(Step step3) {
645660
return new FlowBuilder<SimpleFlow>("flow2")
646-
.start(step3())
661+
.start(step3)
647662
.build();
648663
}
649664
650665
@Bean
651-
public Job job(Flow flow1, Flow flow2) {
652-
return this.jobBuilderFactory.get("job")
666+
public Job job(JobRepository jobRepository, Flow flow1, Flow flow2, Step step4) {
667+
return new JobBuilder("job", jobRepository)
653668
.start(flow1)
654669
.split(new SimpleAsyncTaskExecutor())
655670
.add(flow2)
656-
.next(step4())
671+
.next(step4)
657672
.end()
658673
.build();
659674
}
@@ -699,23 +714,23 @@ Java::
699714
The following Java example shows how to declare a flow as a reference to a flow defined
700715
elsewhere:
701716
+
702-
.Java Confguration
717+
.Java Configuration
703718
[source, java]
704719
----
705720
@Bean
706-
public Job job(JobRepository jobRepository) {
721+
public Job job(JobRepository jobRepository, Flow flow1, Step step3) {
707722
return new JobBuilder("job", jobRepository)
708-
.start(flow1())
709-
.next(step3())
723+
.start(flow1)
724+
.next(step3)
710725
.end()
711726
.build();
712727
}
713728
714729
@Bean
715-
public Flow flow1() {
730+
public Flow flow1(Step step1, Step step2) {
716731
return new FlowBuilder<SimpleFlow>("flow1")
717-
.start(step1())
718-
.next(step2())
732+
.start(step1)
733+
.next(step2)
719734
.build();
720735
}
721736
----
@@ -764,25 +779,25 @@ The following example shows an example of a `JobStep` in Java:
764779
[source, java]
765780
----
766781
@Bean
767-
public Job jobStepJob(JobRepository jobRepository) {
782+
public Job jobStepJob(JobRepository jobRepository, Step jobStepJobStep1) {
768783
return new JobBuilder("jobStepJob", jobRepository)
769-
.start(jobStepJobStep1(null))
784+
.start(jobStepJobStep1)
770785
.build();
771786
}
772787
773788
@Bean
774-
public Step jobStepJobStep1(JobLauncher jobLauncher, JobRepository jobRepository) {
789+
public Step jobStepJobStep1(JobRepository jobRepository, JobLauncher jobLauncher, Job job, JobParametersExtractor jobParametersExtractor) {
775790
return new StepBuilder("jobStepJobStep1", jobRepository)
776-
.job(job())
791+
.job(job)
777792
.launcher(jobLauncher)
778-
.parametersExtractor(jobParametersExtractor())
793+
.parametersExtractor(jobParametersExtractor)
779794
.build();
780795
}
781796
782797
@Bean
783798
public Job job(JobRepository jobRepository) {
784799
return new JobBuilder("job", jobRepository)
785-
.start(step1())
800+
// ...
786801
.build();
787802
}
788803

0 commit comments

Comments
 (0)