How to Use the @KeyFlow DSL Annotation for Reverse Modeling and Visualizing Business Processes

The @KeyFlow DSL annotation marks core business methods in the cp-ddd-framework, enabling the visualization Maven plugin to parse source code, reverse-engineer domain flows, and render PlantUML diagrams of your actual business processes.

The cp-ddd-framework provides a domain-driven design infrastructure for Java applications. By applying the @KeyFlow DSL annotation to your service methods, you enable the framework's visualization engine to perform reverse modeling—extracting the actual business process architecture directly from source code and rendering it as interactive diagrams.

Understanding the Reverse Engineering Pipeline

The framework transforms annotated source code into visual documentation through a multi-stage pipeline. Each component has a specific responsibility in extracting, aggregating, and rendering the domain model.

DSL Definition in KeyFlow.java

The annotation itself is defined in dddplus-spec/src/main/java/io/github/dddplus/dsl/KeyFlow.java. This interface declares the metadata attributes that describe a business flow, including actor, produceEvent, async, and usecase. These attributes drive how the method appears in the final diagram.

AST Parsing and Model Extraction

When the visualization goal executes, KeyFlowAnnotationParser.java (located in dddplus-visualization/src/main/java/io/github/dddplus/ast/parser/KeyFlowAnnotationParser.java) reads the JavaParser AST node for each annotated method. It instantiates a KeyFlowEntry object that encapsulates the method signature, remark, actor class, and event types.

The KeyFlowAstNodeVisitor.java (in dddplus-visualization/src/main/java/io/github/dddplus/ast/KeyFlowAstNodeVisitor.java) traverses the entire source tree, filtering out deprecated or ignored methods, and registers each valid KeyFlowEntry with the central report.

Aggregation via ReverseEngineeringModel and KeyFlowReport

The ReverseEngineeringModel serves as the internal aggregation layer that gathers aggregates, key flows, and domain events into a cohesive representation. The KeyFlowReport.java (in dddplus-visualization/src/main/java/io/github/dddplus/ast/report/KeyFlowReport.java) stores all KeyFlowEntry instances, groups them by their actor attribute, and provides orphan-flow detection to identify methods whose declared actor differs from their containing class.

Rendering with PlantUmlRenderer

Finally, PlantUmlRenderer.java (located in dddplus-visualization/src/main/java/io/github/dddplus/ast/view/PlantUmlRenderer.java) transforms the aggregated model into PlantUML syntax. It renders actors as class boxes, key flows as operations with stereotypes (e.g., <<async>>), and events as directed arrows.

Annotating Your Code with @KeyFlow

To participate in reverse modeling, mark your application service methods with the annotation and configure its attributes to reflect the domain reality.

import io.github.dddplus.dsl.KeyFlow;

public class OrderAppService {

    /** The central “submit order” use‑case. */
    @KeyFlow(
        remark = "统一接单",
        actor  = Order.class,          // the domain object that owns the flow
        produceEvent = OrderSubmitted.class,
        async = true,                  // the flow runs asynchronously
        usecase = true)                // the method belongs to the application layer
    public void submitOrder(OrderDto dto) throws BizException {
        // business logic …
    }
}

Key Attributes Explained

  • actor: The domain class that owns the flow. The diagram will group this method under that actor's box.
  • produceEvent: Domain events emitted by the flow, rendered as outgoing arrows in the UML.
  • async: Adds an <<async>> stereotype to indicate asynchronous execution.
  • usecase: Marks the method as part of the application/use-case layer.
  • remark: Human-readable description displayed beside the flow node.
  • name: Override the method name for the diagram when the source name doesn't match the ubiquitous language.
  • polymorphism: Indicates multiple implementations, shown as a fork in the diagram.

Generating Visualizations with the Maven Plugin

The ModelingVisualizationMojo.java binds the entire pipeline to a Maven goal, allowing you to generate diagrams as part of your build process.

Configuration

Add the plugin to your pom.xml:

<plugin>
    <groupId>io.github.dddplus</groupId>
    <artifactId>dddplus-maven-plugin</artifactId>
    <version>latest-release</version>
    <executions>
        <execution>
            <goals>
                <goal>visualization</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Execution

Run the visualization goal to parse your source tree and emit PlantUML files:

mvn dddplus:visualization

The plugin scans src/main/java, extracts all @KeyFlow annotations, builds the ReverseEngineeringModel, and writes the output to target/dddplus/visualization/, typically including key-flows.puml.

Interpreting the Output and Detecting Architectural Drift

The generated PlantUML diagrams provide a faithful representation of your runtime architecture as defined in the source code.

Sample Output

For the OrderAppService example above, PlantUmlRenderer produces syntax similar to:

@startuml
skinparam classAttributeIconSize 0

class Order {
    + submitOrder(OrderDto) <<async>> /统一接单
}
Order --> OrderSubmitted : <<event>>
@enduml

This renders an Order class box containing the submitOrder operation, annotated with the async stereotype and remark, plus an outgoing arrow to the OrderSubmitted event.

Detecting Orphan Flows

The KeyFlowReport automatically identifies orphan flows—methods where the declared actor attribute differs from the containing class. These indicate potential architectural drift, such as a service method incorrectly claiming ownership by an unrelated aggregate. Review these discrepancies in the report output to maintain alignment between your code and domain model.

Summary

  • The @KeyFlow DSL annotation in cp-ddd-framework marks core business methods for reverse engineering.
  • The visualization pipeline parses annotations via KeyFlowAnnotationParser, aggregates them into a ReverseEngineeringModel through KeyFlowReport, and renders PlantUML diagrams via PlantUmlRenderer.
  • Configure the dddplus-maven-plugin with the visualization goal to automate diagram generation during your build.
  • Use attributes like actor, produceEvent, and async to control diagram semantics and detect architectural drift through orphan flow analysis.

Frequently Asked Questions

What is the difference between the actor attribute and the containing class?

The containing class is the Java type where the method physically resides, while the actor attribute specifies the domain aggregate or entity that logically owns the business flow. When these differ, the KeyFlowReport flags an orphan flow, helping you identify services that may be misplaced or violating aggregate boundaries.

Can I use @KeyFlow on private or protected methods?

The KeyFlowAstNodeVisitor filters out non-public methods during AST traversal. While the parser may log a warning, private and protected methods will not appear in the generated diagrams. Always place the annotation on public service methods to ensure they are captured in the reverse engineering model.

How do I visualize asynchronous processes and domain events?

Set async = true in the annotation to append the <<async>> stereotype to the operation in the PlantUML output. Use the produceEvent attribute to declare emitted domain events; the PlantUmlRenderer will draw directed arrows from the actor to the event classes, clearly showing the flow of side effects.

What should I do if the generated diagram shows orphan flows?

Orphan flows indicate a mismatch between the method's physical location and its declared logical actor. Review the KeyFlowReport output to identify these discrepancies. Refactor the code to move the method to the correct application service or adjust the actor attribute to reflect the actual ownership, ensuring your visualized architecture aligns with your domain model.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →