@@ -7,6 +7,21 @@ necessarily mean that the `Job` should fail. Furthermore, there may be more than
77of "`success`" that determines which `Step` should be executed next. Depending upon how a
88group 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::
699714The following Java example shows how to declare a flow as a reference to a flow defined
700715elsewhere:
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
783798public Job job(JobRepository jobRepository) {
784799 return new JobBuilder("job", jobRepository)
785- .start(step1())
800+ // ...
786801 .build();
787802}
788803
0 commit comments