The Problem
A real pipeline has many steps — fetch context, rebase, run tests, run AI assessments, judge output, generate a report. Passing every leaf step to a single top-level constructor produces an argument list that’s hard to read, hard to test, and hard to explain:The Pattern
Pre-assemble sub-workflows as named Spring beans. The top-level workflow takes phases, not leaves:The Factory
The Spring@Configuration class is the wiring hub. It assembles each phase as a @Bean. Because Workflow<I, O> implements Step<I, O>, sub-workflows compose directly into parent workflows with no adapter needed.
Why This Structure
Separation of concerns: the workflow is a structural description — it answers “what runs when.” The factory is the wiring layer — it answers “what object gets what dependency.” Mixing them produces the 13-argument constructor. Independent testability: each sub-workflow is aWorkflow bean that can be tested in isolation with a minimal set of mock steps. You don’t need to construct all 13 collaborators to test the AI assessment phase:
PrReviewDslWorkflow sees the four phases and the gate. A reader of PrReviewConfig.assessAndReport() sees the five steps. Neither method is overwhelmed by the other’s details.
What Other Frameworks Do
This is the standard pattern across Java workflow and batch frameworks:- LangChain4j —
@SequenceAgent(subAgents = {A.class, B.class})references agents (phases), not the services inside them. The orchestrator doesn’t know how agentAis wired. - Google ADK Java —
SequentialAgent.builder().addSubAgent(parallelAgent).build()whereparallelAgentis already assembled. Leaf services stay inside sub-agents. - Spring Batch —
JobreferencesStepbeans. AStepmay contain anItemReader,ItemProcessor, andItemWriter, but the job definition never sees those — it sees only the step.
Summary
| Concern | Where it lives |
|---|---|
| Pipeline structure (what runs when) | PrReviewDslWorkflow constructor |
| Sub-workflow assembly | @Bean methods in @Configuration |
| Leaf step construction | @Bean methods in @Configuration |
| Service/judge injection | @Bean method parameters |
DSL Primitives
Full vocabulary of composable primitives
API Reference
Sub-workflow composition, AgentContext, StepRunner