This page defines the dependency-injection vocabulary as Vauban materialises it. The model follows the Jakarta CDI 4.1 spec; implementation choices are described in Internals.

Bean

A bean is a class managed by the container: its lifecycle, its dependency resolution and its scope are controlled by Vauban.

Three conditions are enough for a class to become a Vauban bean:

  1. The class is annotated with a scope (@ApplicationScoped, @Singleton, @Dependent, @RequestScoped) or a stereotype.

  2. The class is visible from the module-info.java (exports or same module).

  3. The class shows up in the index produced by vauban-indexer at compile time.

At compile time, every bean receives two generated artefacts:

  • a _Factory — implements BeanFactory<T> and knows how to instantiate the bean;

  • a _ClientProxy — only for normal scopes; intercepts calls and delegates to the active context.

Scope

A scope defines an instance’s lifetime and the context that holds it.

Diagram

Implemented scopes: see the usage table.

Qualifier

A qualifier is a runtime annotation that discriminates beans of the same type. The Default qualifier is implicit. CDI ships @Default, @Any, @Named; Vauban supports all custom qualifiers, including those with @Nonbinding members.

Producer

A @Produces method or field produces a bean whose instantiation is not controlled by the container but by user code. The associated disposer (@Disposes) runs on destruction. Vauban emits a _ProducerFactory per producer method.

Observer

An observer is a @Observes or @ObservesAsync method that reacts to an application event. Async observers are dispatched on virtual threads. Observer resolution is static: the EventDispatcher consults a table built at compile time.

Interceptor

An interceptor wraps a method invocation (@AroundInvoke) or constructor (@AroundConstruct). Interceptor chains are resolved at compile time and stored in the bean’s _Factory.

BeanManager

The BeanManager is CDI’s SPI façade. Vauban exposes it as VaubanBeanManager, read-only for application code. It allows:

  • programmatic bean resolution (getBeans(Type, Qualifier…​));

  • observer resolution;

  • access to active contexts.

The historical mutable methods (addBean, addObserverMethod) are unavailable: everything is frozen at build time.

Injection graph

Diagram

The user never touches the _Factory classes. They call Vauban.bootstrap(), select a root bean, and the container does the rest.

Build Compatible Extensions

CDI 4.1 introduces Build Compatible Extensions (BCEs): @Discovery, @Enhancement, @Registration, @Synthesis, @Validation hooks executed at compile time. Vauban supports them natively since its entire flow is compile-time. See vauban-test-suite for custom BCE examples.

Differences from CDI Full

Vauban implements the Lite profile. The following are absent:

  • runtime portable extensions (Extension, BeforeBeanDiscovery, etc.) — replaced by BCEs;

  • @Specializes;

  • @ConversationScoped;

  • passivation (PassivationCapable);

  • EL (Expression Language) wired into managed beans.