Skip to content

Commit

Permalink
ArC: update documentation to CDI 4.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Ladicek committed Apr 24, 2024
1 parent 7fe58ad commit a8d09a7
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 23 deletions.
12 changes: 6 additions & 6 deletions docs/src/main/asciidoc/cdi-integration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ include::_attributes.adoc[]
:extensions: io.quarkus:quarkus-arc

ArC, the CDI container in Quarkus, is bootstrapped at build time.
To integrate with the container, https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#spi_lite[CDI Build Compatible Extensions, window="_blank"] can be used, as well as a Quarkus-specific extension API.
To integrate with the container, https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#spi_lite[CDI Build Compatible Extensions, window="_blank"] can be used, as well as a Quarkus-specific extension API.
CDI Portable Extensions are not and cannot be supported.
This guide focuses on the Quarkus-specific extensions API.
Expand All @@ -40,7 +40,7 @@ In the following sections we will describe all the relevant build items and comm
== Metadata Sources

Classes and annotations are the primary source of bean-level metadata.
The initial metadata are read from the _bean archive index_, an immutable https://github.com/wildfly/jandex[Jandex index, window="_blank"] which is built from various sources during <<cdi-reference.adoc#bean_discovery,bean discovery>>.
The initial metadata are read from the _bean archive index_, an immutable https://github.com/smallrye/jandex[Jandex index, window="_blank"] which is built from various sources during <<cdi-reference.adoc#bean_discovery,bean discovery>>.
However, extensions can add, remove or transform the metadata at certain stages of the bootstrap.
Moreover, extensions can also register <<synthetic_beans,synthetic components>>.
This is an important aspect to realize when integrating CDI components in Quarkus.
Expand Down Expand Up @@ -93,8 +93,8 @@ NOTE: If no default scope is specified the `@Dependent` pseudo-scope is used.

=== _Reason 2_: Class Is Discovered but Has No Bean Defining Annotation

In Quarkus, the application is represented by a single bean archive with the https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#default_bean_discovery[bean discovery mode `annotated`, window="_blank"].
Therefore, bean classes that don't have a https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#bean_defining_annotations[bean defining annotation, window="_blank"] are ignored.
In Quarkus, the application is represented by a single bean archive with the https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#default_bean_discovery[bean discovery mode `annotated`, window="_blank"].
Therefore, bean classes that don't have a https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#bean_defining_annotations[bean defining annotation, window="_blank"] are ignored.
Bean defining annotations are declared on the class-level and include scopes, stereotypes and `@Interceptor`.

_Solution 1_: Use the `AutoAddScopeBuildItem`. This build item can be used to add a scope to a class that meets certain conditions.
Expand Down Expand Up @@ -163,7 +163,7 @@ _Solution_: Use the `AdditionalBeanBuildItem` as described in <<additional_bean_
== Use Case - I Need To Transform Annotation Metadata

In some cases, it's useful to be able to modify the annotation metadata.
Quarkus provides a powerful alternative to https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#process_annotated_type[`jakarta.enterprise.inject.spi.ProcessAnnotatedType`, window="_blank"] and https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#bce_enhancement[`jakarta.enterprise.inject.build.compatible.spi.Enhancement`, window="_blank"].
Quarkus provides a powerful alternative to https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#process_annotated_type[`jakarta.enterprise.inject.spi.ProcessAnnotatedType`, window="_blank"] and https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#bce_enhancement[`jakarta.enterprise.inject.build.compatible.spi.Enhancement`, window="_blank"].
With an `AnnotationsTransformerBuildItem` it's possible to override the annotations that exist on bean classes.

NOTE: Keep in mind that annotation transformers must be produced _before_ the bean discovery starts.
Expand Down Expand Up @@ -282,7 +282,7 @@ void doSomethingWithNamedBeans(SynthesisFinishedBuildItem synthesisFinished, Bui
Sometimes it is practical to be able to register a _synthetic bean_.
Bean attributes of a synthetic bean are not derived from a Java class, method or field.
Instead, all the attributes are defined by an extension.
In regular CDI, this could be achieved using the https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#after_bean_discovery[`AfterBeanDiscovery.addBean()`, window="_blank"] and https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#bce_synthesis[`SyntheticComponents.addBean()`] methods.
In regular CDI, this could be achieved using the https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#after_bean_discovery[`AfterBeanDiscovery.addBean()`, window="_blank"] and https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#bce_synthesis[`SyntheticComponents.addBean()`] methods.

_Solution_: If you need to register a synthetic bean then use the `SyntheticBeanBuildItem`.

Expand Down
11 changes: 8 additions & 3 deletions docs/src/main/asciidoc/cdi-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ include::_attributes.adoc[]
:topics: cdi,arc,injection,interceptor,observer
:extensions: io.quarkus:quarkus-arc

Quarkus DI solution (also called ArC) is based on the https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html[Jakarta Contexts and Dependency Injection 4.0, window="_blank"] specification.
Quarkus DI solution (also called ArC) is based on the https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html[Jakarta Contexts and Dependency Injection 4.1, window="_blank"] specification.
It implements the CDI Lite specification, with selected improvements on top, and passes the CDI Lite TCK.
It does not implement CDI Full.
See also <<supported_features_and_limitations,the list of supported features and limitations>>.
Expand All @@ -28,7 +28,7 @@ NOTE: Most of the existing CDI code should work just fine but there are some sma
Bean discovery in CDI is a complex process which involves legacy deployment structures and accessibility requirements of the underlying module architecture.
However, Quarkus is using a *simplified bean discovery*.
There is only single bean archive with the https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#default_bean_discovery[bean discovery mode `annotated`, window="_blank"] and no visibility boundaries.
There is only single bean archive with the https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#default_bean_discovery[bean discovery mode `annotated`, window="_blank"] and no visibility boundaries.
The bean archive is synthesized from:
Expand All @@ -38,7 +38,7 @@ The bean archive is synthesized from:
* dependencies referenced by `quarkus.index-dependency` in `application.properties`,
* and Quarkus integration code.
Bean classes that don't have a https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#bean_defining_annotations[bean defining annotation, window="_blank"] are not discovered.
Bean classes that don't have a https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#bean_defining_annotations[bean defining annotation, window="_blank"] are not discovered.
This behavior is defined by CDI.
But producer methods and fields and observer methods are discovered even if the declaring class is not annotated with a bean defining annotation (this behavior is different to what is defined in CDI).
In fact, the declaring bean classes are considered annotated with `@Dependent`.
Expand Down Expand Up @@ -220,6 +220,11 @@ The following features from CDI Full are also supported:
* `@SessionScoped`
** Only with the Undertow extension; see xref:cdi.adoc#bean-scope-available[here] for details

The _method invokers_ implementation supports asynchronous methods.
The following methods are considered asynchronous and `@Dependent` instances are only destroyed when the asynchronous action completes:

* methods that declare a return type of `CompletionStage`, `Uni`, or `Multi`

NOTE: These additional features are not covered by the CDI Lite TCK.

[[nonstandard_features]]
Expand Down
18 changes: 9 additions & 9 deletions docs/src/main/asciidoc/cdi.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
include::_attributes.adoc[]
:categories: core
:keywords: qualifier event interceptor observer arc
:summary: Quarkus DI solution is based on the [Jakarta Contexts and Dependency Injection 4.0](https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html) specification. This guide explains the basics of CDI.
:summary: Quarkus DI solution is based on the [Jakarta Contexts and Dependency Injection 4.1](https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html) specification. This guide explains the basics of CDI.
:numbered:
:sectnums:
:sectnumlevels: 4
:topics: cdi,arc,injection,interceptor,observer
:extensions: io.quarkus:quarkus-arc

In this guide we're going to describe the basic principles of the Quarkus programming model that is based on the https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html[Jakarta Contexts and Dependency Injection 4.0, window="_blank"] specification.
In this guide we're going to describe the basic principles of the Quarkus programming model that is based on the https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html[Jakarta Contexts and Dependency Injection 4.1, window="_blank"] specification.
== OK. Let's start simple. What is a bean?
Expand Down Expand Up @@ -104,7 +104,7 @@ public class Translator {
== Can I use setter and constructor injection?

Yes, you can.
In fact, in CDI the "setter injection" is superseded by more powerful https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#initializer_methods[initializer methods, window="_blank"].
In fact, in CDI the "setter injection" is superseded by more powerful https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#initializer_methods[initializer methods, window="_blank"].
Initializers may accept multiple parameters and don't have to follow the JavaBean naming conventions.

.Initialized and Constructor Injection Example
Expand Down Expand Up @@ -134,7 +134,7 @@ It's also not necessary to add `@Inject` if there is only one constructor presen

== You talked about some qualifiers?

https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#qualifiers[Qualifiers, window="_blank"] are annotations that help the container to distinguish beans that implement the same type.
https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#qualifiers[Qualifiers, window="_blank"] are annotations that help the container to distinguish beans that implement the same type.
As we already said a bean is assignable to an injection point if it has all the required qualifiers.
If you declare no qualifier at an injection point the `@Default` qualifier is assumed.

Expand Down Expand Up @@ -163,7 +163,7 @@ public class SuperiorTranslator extends Translator {
}
}
----
<1> `@Superior` is a https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#defining_qualifier_types[qualifier annotation, window="_blank"].
<1> `@Superior` is a https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#defining_qualifier_types[qualifier annotation, window="_blank"].

This bean would be assignable to `@Inject @Superior Translator` and `@Inject @Superior SuperiorTranslator` but not to `@Inject Translator`.
The reason is that `@Inject Translator` is automatically transformed to `@Inject @Default Translator` during typesafe resolution.
Expand Down Expand Up @@ -216,7 +216,7 @@ Therefore, we recommend to stick with `@ApplicationScoped` by default unless the
[[client_proxies]]
== I don't understand the concept of client proxies.
Indeed, the https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#client_proxies[client proxies, window="_blank"] could be hard to grasp, but they provide some useful functionality.
Indeed, the https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#client_proxies[client proxies, window="_blank"] could be hard to grasp, but they provide some useful functionality.
A client proxy is basically an object that delegates all method invocations to a target bean instance.
It's a container construct that implements `io.quarkus.arc.ClientProxy` and extends the bean class.
Expand Down Expand Up @@ -244,7 +244,7 @@ class Translator_ClientProxy extends Translator { <1>
}
}
----
<1> The `Translator_ClientProxy` instance is always injected instead of a direct reference to a https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#contextual_instance[contextual instance, window="_blank"] of the `Translator` bean.
<1> The `Translator_ClientProxy` instance is always injected instead of a direct reference to a https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#contextual_instance[contextual instance, window="_blank"] of the `Translator` bean.
Client proxies allow for:
Expand Down Expand Up @@ -518,10 +518,10 @@ TIP: For more info about events/observers visit https://docs.jboss.org/weld/refe
== Conclusion
In this guide, we've covered some basic topics of the Quarkus programming model that is based on the https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html[Jakarta Contexts and Dependency Injection 4.0, window="_blank"] specification.
In this guide, we've covered some basic topics of the Quarkus programming model that is based on the https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html[Jakarta Contexts and Dependency Injection 4.1, window="_blank"] specification.
Quarkus implements the CDI Lite specification, but not CDI Full.
See also <<cdi-reference.adoc#supported_features_and_limitations,the list of supported features and limitations>>.
There are also quite a few <<cdi-reference#nonstandard_features,non-standard features>> and <<cdi-reference.adoc#build_time_apis,Quarkus-specific APIs>>.
TIP: If you wish to learn more about Quarkus-specific features and limitations there is a Quarkus xref:cdi-reference.adoc[CDI Reference Guide].
We also recommend you to read the https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html[CDI specification] and the https://docs.jboss.org/weld/reference/latest/en-US/html/[Weld documentation] (Weld is a CDI Reference Implementation) to get acquainted with more complex topics.
We also recommend you to read the https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html[CDI specification] and the https://docs.jboss.org/weld/reference/latest/en-US/html/[Weld documentation] (Weld is a CDI Reference Implementation) to get acquainted with more complex topics.
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/getting-started.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ property called `test.url` that is set to the base test URL for situations where

== Working with multi-module project or external modules

Quarkus heavily utilizes https://github.com/wildfly/jandex[Jandex] at build time, to discover various classes or annotations. One immediately recognizable application of this, is CDI bean discovery.
Quarkus heavily utilizes https://github.com/smallrye/jandex[Jandex] at build time, to discover various classes or annotations. One immediately recognizable application of this, is CDI bean discovery.
As a result, most of the Quarkus extensions will not work properly if this build time discovery isn't properly setup.

This index is created by default on the project on which Quarkus is configured for, thanks to our Maven and Gradle plugins.
Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/lifecycle.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ In the JVM mode, there is no real difference, except that `StartupEvent` is alwa
For a native executable build, however, `@Initialized(ApplicationScoped.class)` is fired as *part of the native build process*, whereas `StartupEvent` is fired when the native image is executed.
See xref:writing-extensions.adoc#bootstrap-three-phases[Three Phases of Bootstrap and Quarkus Philosophy] for more details.

NOTE: In CDI applications, an event with qualifier `@Initialized(ApplicationScoped.class)` is fired when the application context is initialized. See https://jakarta.ee/specifications/cdi/2.0/cdi-spec-2.0.html#application_context[the spec, window="_blank"] for more info.
NOTE: In CDI applications, an event with qualifier `@Initialized(ApplicationScoped.class)` is fired when the application context is initialized. See https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#application_context[the spec, window="_blank"] for more info.

[[startup_annotation]]
=== Using `@Startup` to initialize a CDI bean at application startup
Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/spring-di.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ Please note that the Spring support in Quarkus does not start a Spring Applicati
Spring classes and annotations are only used for reading metadata and / or are used as user code method return types or parameter types.
What that means for end users, is that adding arbitrary Spring libraries will not have any effect. Moreover, Spring infrastructure
classes (like `org.springframework.beans.factory.config.BeanPostProcessor` , `org.springframework.context.ApplicationContext` for example) will not be executed.
Regarding the dependency injection in particular, Quarkus uses a Dependency Injection mechanism (called ArC) based on the https://jakarta.ee/specifications/cdi/2.0/cdi-spec-2.0.html[Contexts and Dependency Injection for Java 2.0] specification. If you want to learn more about it, we recommend you to read the xref:cdi.adoc[Quarkus introduction to CDI] and the xref:cdi-reference.adoc#arc-configuration-reference[CDI reference guide]
Regarding the dependency injection in particular, Quarkus uses a Dependency Injection mechanism (called ArC) based on the https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html[Jakarta Contexts and Dependency Injection 4.1] specification. If you want to learn more about it, we recommend you to read the xref:cdi.adoc[Quarkus introduction to CDI] and the xref:cdi-reference.adoc#arc-configuration-reference[CDI reference guide]
The various Spring Boot test features are not supported by Quarkus. For testing purposes, please, check the xref:getting-started-testing.adoc[Quarkus testing guide].

Some known limitations:
Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/writing-extensions.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2389,7 +2389,7 @@ Capabilities should follow the naming conventions of Java packages; e.g. `io.qua
Capabilities provided by core extensions should be listed in the `io.quarkus.deployment.Capability` enum and their name should always start with the `io.quarkus` prefix.

==== Bean Defining Annotations
The CDI layer processes CDI beans that are either explicitly registered or that it discovers based on bean defining annotations as defined in https://jakarta.ee/specifications/cdi/2.0/cdi-spec-2.0.html#bean_defining_annotations[2.5.1. Bean defining annotations]. You can expand this set of annotations to include annotations your extension processes using a `BeanDefiningAnnotationBuildItem` as shown in this `TestProcessor#registerBeanDefinningAnnotations` example:
The CDI layer processes CDI beans that are either explicitly registered or that it discovers based on bean defining annotations as defined in https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#bean_defining_annotations[2.5.1. Bean defining annotations]. You can expand this set of annotations to include annotations your extension processes using a `BeanDefiningAnnotationBuildItem` as shown in this `TestProcessor#registerBeanDefinningAnnotations` example:

.Register a Bean Defining Annotation
[source,java]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ private static Injection forSynthetic(Iterable<TypeAndQualifiers> injectionPoint

private static void validateInjections(InjectionPointInfo injectionPointInfo, BeanType beanType) {
// Mostly validation related to Bean metadata injection restrictions
// see https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.html#bean_metadata
// see https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#bean_metadata
if (beanType == BeanType.MANAGED_BEAN || beanType == BeanType.SYNTHETIC_BEAN || beanType == BeanType.PRODUCER_METHOD) {
// If an Interceptor<T> instance is injected into a bean instance other than an interceptor instance,
// the container automatically detects the problem and treats it as a definition error.
Expand Down

0 comments on commit a8d09a7

Please sign in to comment.