# How to Use the @Governance Annotation for Managing Extension Lifecycle in cp-ddd-framework

> Master extension lifecycle management with the @Governance annotation in cp-ddd-framework. Learn how to monitor, count, and control extension invocations for robust service governance.

- Repository: [Funky Gao/cp-ddd-framework](https://github.com/funkygao/cp-ddd-framework)
- Tags: how-to-guide
- Published: 2026-03-02

---

**The `@Governance` annotation activates service-level governance for public methods in `BaseRouter` subclasses, wrapping extension invocations in an AOP interceptor that handles invocation counting, availability monitoring, performance profiling, and exception-impact control.**

The `funkygao/cp-ddd-framework` provides a DDDplus runtime for orchestrating domain extensions through routers. The `@Governance` annotation serves as a single point of control to monitor and protect the entire extension chain lifecycle, from router entry to result aggregation.

## What Is the @Governance Annotation?

The `@Governance` annotation is defined in [`annotation/Governance.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/annotation/Governance.java) as a method-level marker used exclusively on public methods of `BaseRouter` subclasses. It accepts a single boolean attribute `profiler()` that defaults to `true`, allowing developers to toggle performance profiling for specific router methods.

When present, the annotation signals the framework to apply an AOP interceptor that wraps the actual extension invocation. This interceptor is implemented primarily within `ExtensionInvocationHandler`, which acts as a dynamic proxy responsible for executing extensions while collecting lifecycle metrics.

## How @Governance Manages Extension Lifecycle

The governance interceptor manages four critical lifecycle concerns during extension execution.

### Invocation Counting and Availability Monitoring

Each call to a `@Governance`-annotated method triggers the `ExtensionInvocationHandler` to increment an invocation counter before delegating to the real extension. If the extension throws an exception, the handler logs the failure and decreases the availability metric, providing real-time health indicators for domain services.

### Performance Profiling and Timeouts

When `profiler()` is `true` (the default), the handler captures start and end timestamps around the extension execution. For methods requiring timeout protection, the framework utilizes `ExtensionInvocationHandler.invokeExtensionMethodWithTimeout`, which executes the method via a timed `Future`. If the execution exceeds the configured threshold, an `ExtTimeoutException` is thrown and recorded as a timeout event in the profiler metrics.

### Exception-Impact Control

The framework provides the `IExceptionIgnoreProfilerError` marker interface to fine-tune error reporting. When an exception implements this interface, the `ExtensionInvocationHandler` recognizes it via an `instanceof` check and excludes it from penalizing the profiler’s availability metric. This allows business exceptions to propagate without distorting service health statistics.

## Implementation Architecture

The governance mechanism relies on several key components within the `dddplus-runtime` module:

- **[`annotation/Governance.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/annotation/Governance.java)**: Defines the annotation and its `profiler` attribute.
- **[`runtime/BaseRouter.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/runtime/BaseRouter.java)**: The abstract base class whose public methods can be annotated; provides `forEachExtension` for extension discovery via `InternalIndexer`.
- **[`runtime/ExtensionInvocationHandler.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/runtime/ExtensionInvocationHandler.java)**: The dynamic proxy that intercepts extension calls, implements timeout handling via `invokeExtensionMethodWithTimeout`, and records profiling data.
- **[`runtime/IExceptionIgnoreProfilerError.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/runtime/IExceptionIgnoreProfilerError.java)**: Marker interface to exempt specific exceptions from error metrics.

During application startup, a Spring AOP aspect (referenced in tests as `GovernanceAspect`) detects `@Governance` annotations and weaves the interception logic around the target methods.

## Practical Code Examples

### Basic Router with Governance

The following example from [`BarRouter.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/BarRouter.java) demonstrates standard usage:

```java
// src/test/java/io/github/dddplus/runtime/registry/mock/router/BarRouter.java
@Router(domain = FooDomain.CODE)
@Slf4j
public class BarRouter extends BaseRouter<IFooExt, FooModel> {

    @LogInfo(in = true, out = true)
    @Governance                     // enable profiling (default = true)
    public String submit(FooModel model) {
        int result = forEachExtension(model, IReducer.stopOnFirstMatch(
                i -> i > 1)).execute(model);
        return String.valueOf(result);
    }

    @Governance(profiler = false)   // disable profiling for this method
    public void nonProfiledMethod(FooModel model) {
        // business logic without metrics collection
    }
}

```

### Governance on Domain Policies

The annotation also applies to policy methods, as shown in [`TriggerPolicy.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/TriggerPolicy.java):

```java
// src/test/java/io/github/dddplus/runtime/registry/mock/policy/TriggerPolicy.java
@Policy
public class TriggerPolicy implements IPolicy {
    @Governance                     // governance also works on policies
    public void afterInsert(FooModel model) {
        log.info("foo trigger");
    }
}

```

### Timeout Configuration with Governance

To utilize timeout protection with governance profiling:

```java
@Governance(profiler = true)
public String timedSubmit(FooModel model) {
    // Timeout configured via forEachExtension
    return forEachExtension(model, IReducer.allOf())
            .timeout(500, TimeUnit.MILLISECONDS)
            .execute(model);
}

```

If execution exceeds the threshold, `ExtensionInvocationHandler.invokeExtensionMethodWithTimeout` throws `ExtTimeoutException` and records the timeout in profiler metrics.

## Summary

- The `@Governance` annotation activates service-level governance for public methods in `BaseRouter` subclasses and policy implementations.
- It wraps extension invocations in an AOP interceptor implemented by `ExtensionInvocationHandler`, providing unified lifecycle management.
- Key capabilities include invocation counting, availability monitoring via error-rate tracking, performance profiling with timeout enforcement, and exception-impact control through `IExceptionIgnoreProfilerError`.
- The `profiler()` attribute allows selective enablement of performance metrics per method.
- Governance integrates seamlessly with the DDDplus runtime extension discovery mechanism via `InternalIndexer` and result aggregation through `IReducer`.

## Frequently Asked Questions

### What is the difference between @Governance and standard Spring AOP?

`@Governance` is a domain-specific annotation within the cp-ddd-framework that signals the framework's internal `ExtensionInvocationHandler` to apply DDDplus-specific governance concerns—such as extension timeout handling, availability metrics for domain extensions, and the `IExceptionIgnoreProfilerError` exception filtering. While it leverages Spring AOP mechanisms (as seen in the test suite's `GovernanceAspect`), it specifically targets the lifecycle of extensions orchestrated by `BaseRouter` rather than generic cross-cutting concerns.

### Can I use @Governance on private methods or classes other than BaseRouter?

No. The `@Governance` annotation is designed exclusively for public methods of `BaseRouter` subclasses (routers) and methods of classes annotated with `@Policy`. The framework's AOP pointcuts and the `ExtensionInvocationHandler` proxy mechanism expect the annotated method to be part of the router's public API that orchestrates extensions via `forEachExtension`. Applying it to private methods or non-router classes will result in the annotation being ignored because the interception logic cannot bind to those targets.

### How does the profiler handle timeouts and where is the threshold configured?

When `profiler()` is `true` (default), the `ExtensionInvocationHandler` measures execution latency and can enforce timeouts via `invokeExtensionMethodWithTimeout`. The timeout threshold is not configured directly on the `@Governance` annotation itself; instead, it is specified when calling `forEachExtension(...).timeout(duration, timeUnit)` within the router method. If the extension execution exceeds this threshold, the handler throws `ExtTimeoutException`, which is recorded as a timeout event in the profiler metrics without necessarily decreasing availability, allowing operators to identify slow extensions independently of error rates.

### What exceptions should implement IExceptionIgnoreProfilerError?

Exceptions that represent expected business outcomes or control-flow mechanisms—rather than service failures—should implement `IExceptionIgnoreProfilerError`. When an extension throws such an exception, the `ExtensionInvocationHandler` detects the marker interface and excludes the exception from the availability error-rate calculation. This prevents legitimate business exceptions (such as validation failures, business rule violations, or expected "not found" scenarios) from distorting the service health metrics, ensuring that the profiler reflects only genuine system or unexpected errors that impact service availability.