Files
spring-state-machine-renderer/plan-extended-anaylis/property_resolution.md

2.7 KiB

Spring Property and Value Resolution Strategy

1. The Challenge of "Injected" Metadata

In Spring, metadata (like Queue names, Topic names, or even Event names) is often not hardcoded but injected using various mechanisms. To provide an accurate map, the analyzer must resolve these values.

2. Supported Injection Patterns

Field Injection

@Value("${app.order-queue}")
private String orderQueue;

Static Strategy:

  1. Scan all fields for @Value.
  2. Map FieldName -> Placeholder/Value.
  3. If ${...} is found, resolve it via the PropertyResolver.

Constructor and Setter Injection

public OrderService(@Value("${app.event.submit}") String submitEvent) {
    this.submitEvent = submitEvent;
}

Static Strategy:

  1. Scan constructor/method parameters for @Value.
  2. Trace the assignment to a class field (this.submitEvent = ...).
  3. Store the mapping for that field.

@ConfigurationProperties

@ConfigurationProperties(prefix = "app.messaging")
public class AppProps {
    private String queueName;
}

Static Strategy:

  1. Identify @ConfigurationProperties classes.
  2. Index their fields with the prefix (e.g., app.messaging.queueName).
  3. When these beans are injected into a service, link the service's usage to the resolved property value.

3. Property Resolver (The "Config Scanner")

A component dedicated to building a global map of available properties.

  1. File Scanning: Parse application.properties, application.yml, and bootstrap.yml.
  2. Profile Support: Handle application-{profile}.yml if a profile is active.
  3. Property Map: Create a Map<String, String> of all key-value pairs.

4. Value Propagation (Data Flow)

Once a value is resolved or its placeholder is identified, we track its usage.

Example Trace:

  1. application.yml -> app.queue: "orders"
  2. OrderService -> @Value("${app.queue}") String q; -> this.queue = q;
  3. OrderService.send() -> sm.sendEvent(this.queue);
  4. Resolution: The "Event" for this trigger is "orders".

5. SpEL (Spring Expression Language) Lite

Full SpEL support is hard for static analysis, but we can support "Common Patterns":

  • Simple bean property access: #{myBean.name}
  • System properties: #{systemProperties['user.dir']}
  • Ternary operators: ${app.enabled ? 'active' : 'inactive'}

6. Constant Resolution

If an annotation uses a reference to a constant:

@RabbitListener(queues = MyConstants.ORDER_QUEUE)

Static Strategy:

  1. Use JDT to resolve the QualifiedName (MyConstants.ORDER_QUEUE).
  2. Fetch the TypeDeclaration for MyConstants.
  3. Find the VariableDeclarationFragment for ORDER_QUEUE and extract its literal initializer.