Interface ProcessingLifecycleInterceptor


@Internal public interface ProcessingLifecycleInterceptor
Seam that is invoked immediately around every action executed by a UnitOfWork, on the very thread that runs the action.

Every registered phase action (INVOCATION, PREPARE_COMMIT, COMMIT, AFTER_COMMIT, ...), as well as the completion- and error-handler dispatch sites, passes through this interceptor. This makes it the single choke point for bridging thread-bound state, such as distributed tracing context, MDC, or security context, into the segments that the framework executes on its own work scheduler threads.

The three dispatch kinds are exposed as three separate, all-abstract methods, interceptPhase(ProcessingContext, Phase, Supplier), interceptCompletion(ProcessingContext, Runnable), and interceptError(ProcessingContext, Phase, Throwable, Runnable), rather than a single method discriminated by a nullable flag. The compiler therefore forces every implementation to consider all three sites, removing the risk of an implementation that silently covers phase actions while missing the completion- or error-handler dispatch. Implementations that want to apply the same behavior uniformly to all three kinds (the common case for state-bridging infrastructure such as a tracing binding) should use intercept(UniformInterceptor) instead of implementing this interface directly.

No interceptor is installed by default: UnitOfWorkConfiguration.defaultValues() leaves the interceptor null, and the UnitOfWork then runs actions directly, adding no behavior and no overhead. An interceptor is meant to be installed by infrastructure (for example a tracing binding) through UnitOfWorkConfiguration.addLifecycleInterceptor(ProcessingLifecycleInterceptor), which composes contributors via andThen(ProcessingLifecycleInterceptor) so multiple installers never clobber one another.

Implementations run on the action's thread and MUST restore any thread-bound state they mutate before returning, regardless of the action's outcome (typically via try-with-resources).

Evolution policy: should a future minor release introduce another dispatch-kind method, its default implementation MUST delegate to an existing method of this interface (safe-by-default), never pass through the action unintercepted (skip-by-default). This preserves the guarantee that a wrap-everything implementor (any implementation obtained through intercept(UniformInterceptor)) keeps covering every dispatch site across releases.

Since:
5.3.0
Author:
Mateusz Nowak
  • Method Details

    • interceptPhase

      Invoked on the thread that executes the action, immediately around it. This is the seam for bridging thread-bound state (tracing context, MDC, security) into phase actions registered in a lifecycle phase.
      Parameters:
      context - the ProcessingContext of the UnitOfWork executing the action
      phase - the ProcessingLifecycle.Phase the action executes in
      action - the action to execute, returning a CompletableFuture that completes when the action is done
      Returns:
      the result of executing the action
    • interceptCompletion

      void interceptCompletion(ProcessingContext context, Runnable action)
      Invoked on the thread that executes the action, immediately around it. This is the seam for bridging thread-bound state into a whenComplete-handler dispatch, running after the lifecycle completed successfully.
      Parameters:
      context - the ProcessingContext of the UnitOfWork whose completion handler is dispatched
      action - the completion-handler dispatch to execute
    • interceptError

      void interceptError(ProcessingContext context, @Nullable ProcessingLifecycle.Phase failedPhase, Throwable cause, Runnable action)
      Invoked on the thread that executes the action, immediately around it. This is the seam for bridging thread-bound state into an onError-handler dispatch, running after the lifecycle failed.
      Parameters:
      context - the ProcessingContext of the UnitOfWork whose error handler is dispatched
      failedPhase - the ProcessingLifecycle.Phase whose action failed, or null when the failure preceded the first phase
      cause - the failure that moved the lifecycle into its error state
      action - the error-handler dispatch to execute
    • intercept

      Creates a ProcessingLifecycleInterceptor that applies the given interceptor uniformly to all three dispatch kinds: phase actions, completion-handler dispatch, and error-handler dispatch.

      This is the shape most infrastructure contributors need: state-bridging behavior (restoring thread-locals, activating a live span, ...) that does not depend on which kind of dispatch is being intercepted, expressed as a single lambda that can never under-cover a dispatch site.

      Parameters:
      interceptor - the kind-agnostic interceptor applied to every dispatch site
      Returns:
      a ProcessingLifecycleInterceptor delegating every dispatch kind to interceptor
    • andThen

      Composes this interceptor with the other one, invoking this on the outside and other on the inside (closest to the action), per dispatch kind. Composition ensures multiple contributors never clobber each other.
      Parameters:
      other - the interceptor to invoke inside this one
      Returns:
      a composed ProcessingLifecycleInterceptor