From ef3c0b7e066f6c6dee606444e8cca1c9a0cf9426 Mon Sep 17 00:00:00 2001
From: Matej Novotny
Date: Wed, 6 Sep 2023 12:26:59 +0200
Subject: [PATCH] Arc - Revisit BeanContainer API
---
.../lambda/runtime/AmazonLambdaRecorder.java | 8 +-
.../io/quarkus/arc/runtime/BeanContainer.java | 116 ++++++++++++------
.../arc/runtime/BeanContainerImpl.java | 39 ++----
.../security/runtime/ElytronRecorder.java | 2 +-
.../FunqyCloudFunctionsBindingRecorder.java | 2 +-
.../grpc/auth/GrpcSecurityRecorder.java | 4 +-
.../orm/runtime/HibernateOrmRecorder.java | 2 +-
.../client/runtime/InfinispanRecorder.java | 2 +-
.../runtime/tracing/TracerRecorder.java | 2 +-
.../InstrumentationRecorder.java | 2 +-
.../common/runtime/ArcBeanFactory.java | 37 +++---
.../runtime/ResteasyReactiveRecorder.java | 2 +-
.../security/webauthn/WebAuthnRecorder.java | 6 +-
.../runtime/SmallRyeGraphQLRecorder.java | 2 +-
.../runtime/SmallRyeMetricsRecorder.java | 2 +-
.../quarkus/devui/runtime/DevUIRecorder.java | 2 +-
.../ContinuousTestingRecorder.java | 2 +-
.../ManagementInterfaceSecurityRecorder.java | 2 +-
.../security/HttpSecurityRecorder.java | 2 +-
.../java/io/quarkus/arc/ArcContainer.java | 6 -
.../io/quarkus/arc/impl/ArcContainerImpl.java | 4 +-
.../src/main/java/org/acme/AcmeRecorder.java | 2 +-
.../quarkus/extest/runtime/TestRecorder.java | 2 +-
23 files changed, 136 insertions(+), 114 deletions(-)
diff --git a/extensions/amazon-lambda/runtime/src/main/java/io/quarkus/amazon/lambda/runtime/AmazonLambdaRecorder.java b/extensions/amazon-lambda/runtime/src/main/java/io/quarkus/amazon/lambda/runtime/AmazonLambdaRecorder.java
index f8fb6d5b76568..b97b508b5ada1 100644
--- a/extensions/amazon-lambda/runtime/src/main/java/io/quarkus/amazon/lambda/runtime/AmazonLambdaRecorder.java
+++ b/extensions/amazon-lambda/runtime/src/main/java/io/quarkus/amazon/lambda/runtime/AmazonLambdaRecorder.java
@@ -75,11 +75,11 @@ public void setBeanContainer(BeanContainer container) {
*/
public static void handle(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
if (streamHandlerClass != null) {
- RequestStreamHandler handler = beanContainer.beanInstance(streamHandlerClass);
+ RequestStreamHandler handler = beanContainer.resolveBean(streamHandlerClass);
handler.handleRequest(inputStream, outputStream, context);
} else {
Object request = objectReader.readValue(inputStream);
- RequestHandler handler = beanContainer.beanInstance(handlerClass);
+ RequestHandler handler = beanContainer.resolveBean(handlerClass);
Object response = handler.handleRequest(request, context);
objectWriter.writeValue(outputStream, response);
}
@@ -163,7 +163,7 @@ public void startPollLoop(ShutdownContext context, LaunchMode launchMode) {
@Override
protected Object processRequest(Object input, AmazonLambdaContext context) throws Exception {
- RequestHandler handler = beanContainer.beanInstance(handlerClass);
+ RequestHandler handler = beanContainer.resolveBean(handlerClass);
return handler.handleRequest(input, context);
}
@@ -185,7 +185,7 @@ protected boolean isStream() {
@Override
protected void processRequest(InputStream input, OutputStream output, AmazonLambdaContext context)
throws Exception {
- RequestStreamHandler handler = beanContainer.beanInstance(streamHandlerClass);
+ RequestStreamHandler handler = beanContainer.resolveBean(streamHandlerClass);
handler.handleRequest(input, output, context);
}
diff --git a/extensions/arc/runtime/src/main/java/io/quarkus/arc/runtime/BeanContainer.java b/extensions/arc/runtime/src/main/java/io/quarkus/arc/runtime/BeanContainer.java
index 7594bb3bb9c47..f84a14bd6abce 100644
--- a/extensions/arc/runtime/src/main/java/io/quarkus/arc/runtime/BeanContainer.java
+++ b/extensions/arc/runtime/src/main/java/io/quarkus/arc/runtime/BeanContainer.java
@@ -2,6 +2,8 @@
import java.lang.annotation.Annotation;
+import io.quarkus.arc.Arc;
+import io.quarkus.arc.ArcContainer;
import io.quarkus.arc.ManagedContext;
/**
@@ -10,35 +12,41 @@
public interface BeanContainer {
/**
- * Returns a bean instance for given bean type and qualifiers.
- *
- * This method follows standard CDI rules meaning that if there are two or more eligible beans, an ambiguous
- * dependency exception is thrown.
- * Note that the method is allowed to return {@code null} if there is no matching bean which allows
- * for fallback implementations.
+ * A convenience method returning an instance of {@link ArcContainer} which is an entry point to the CDI container.
*
- * @param type
- * @param qualifiers
- * @return a bean instance or {@code null} if no matching bean is found
+ * @return instance of {@link ArcContainer}
*/
- default T beanInstance(Class type, Annotation... qualifiers) {
- return beanInstanceFactory(type, qualifiers).create().get();
+ default ArcContainer container() {
+ return Arc.container();
}
/**
- * This method is deprecated and will be removed in future versions.
- * Use {@link #beanInstance(Class, Annotation...)} instead.
- *
- * As opposed to {@link #beanInstance(Class, Annotation...)}, this method does NOT follow CDI
- * resolution rules and in case of ambiguous resolution performs a choice based on the class type parameter.
+ * Attempts to resolve a bean instance for given bean type and qualifiers.
+ *
+ * Note that the method deliberately returns {@code null} if there is no matching bean found allowing caller to
+ * detect such case and implement arbitrary fallback logic.
+ *
+ * Ambiguities are resolved as per CDI specification, possibly leading to an exception if there are multiple
+ * matching beans.
*
- * @param type
- * @param qualifiers
+ * @param beanType type of the bean
+ * @param beanQualifiers bean qualifiers
* @return a bean instance or {@code null} if no matching bean is found
*/
- @Deprecated
- default T instance(Class type, Annotation... qualifiers) {
- return instanceFactory(type, qualifiers).create().get();
+ T tryResolveBean(Class beanType, Annotation... beanQualifiers);
+
+ /**
+ * Resolves a bean instance for given bean type and qualifiers.
+ *
+ * Performs standard CDI resolution meaning it either returns a bean instance or throws a corresponding exception
+ * if the dependency is either unsatisfied or ambiguous.
+ *
+ * @param beanType type of the bean
+ * @param beanQualifiers bean qualifiers
+ * @return a bean instance; never {@code null}
+ */
+ default T resolveBean(Class beanType, Annotation... beanQualifiers) {
+ return container().select(beanType, beanQualifiers).get();
}
/**
@@ -55,20 +63,6 @@ default T instance(Class type, Annotation... qualifiers) {
*/
Factory beanInstanceFactory(Class type, Annotation... qualifiers);
- /**
- * This method is deprecated and will be removed in future versions.
- * Use {@link #beanInstanceFactory(Class, Annotation...)} instead.
- *
- * As opposed to {@link #beanInstanceFactory(Class, Annotation...)}, this method does NOT follow CDI
- * resolution rules and in case of ambiguous resolution performs a choice based on the class type parameter.
- *
- * @param type
- * @param qualifiers
- * @return a bean instance factory, never {@code null}
- */
- @Deprecated
- Factory instanceFactory(Class type, Annotation... qualifiers);
-
/**
*
* ManagedContext requestContext = beanContainer.requestContext();
@@ -89,6 +83,58 @@ default T instance(Class type, Annotation... qualifiers) {
*/
ManagedContext requestContext();
+ /**
+ * This method is deprecated and will be removed in future versions.
+ * Use {@link #tryResolveBean(Class, Annotation...)} instead.
+ *
+ * Returns a bean instance for given bean type and qualifiers.
+ *
+ * This method follows standard CDI rules meaning that if there are two or more eligible beans, an ambiguous
+ * dependency exception is thrown.
+ * Note that the method is allowed to return {@code null} if there is no matching bean which allows
+ * for fallback implementations.
+ *
+ * @param type
+ * @param qualifiers
+ * @return a bean instance or {@code null} if no matching bean is found
+ */
+ @Deprecated(forRemoval = true)
+ default T beanInstance(Class type, Annotation... qualifiers) {
+ return beanInstanceFactory(type, qualifiers).create().get();
+ }
+
+ /**
+ * This method is deprecated and will be removed in future versions.
+ * Use {@link #tryResolveBean(Class, Annotation...)} instead.
+ *
+ * Use {@link #beanInstance(Class, Annotation...)} instead.
+ *
+ * As opposed to {@link #beanInstance(Class, Annotation...)}, this method does NOT follow CDI
+ * resolution rules and in case of ambiguous resolution performs a choice based on the class type parameter.
+ *
+ * @param type
+ * @param qualifiers
+ * @return a bean instance or {@code null} if no matching bean is found
+ */
+ @Deprecated(forRemoval = true)
+ default T instance(Class type, Annotation... qualifiers) {
+ return instanceFactory(type, qualifiers).create().get();
+ }
+
+ /**
+ * This method is deprecated and will be removed in future versions.
+ * Use {@link #beanInstanceFactory(Class, Annotation...)} instead.
+ *
+ * As opposed to {@link #beanInstanceFactory(Class, Annotation...)}, this method does NOT follow CDI
+ * resolution rules and in case of ambiguous resolution performs a choice based on the class type parameter.
+ *
+ * @param type
+ * @param qualifiers
+ * @return a bean instance factory, never {@code null}
+ */
+ @Deprecated(forRemoval = true)
+ Factory instanceFactory(Class type, Annotation... qualifiers);
+
interface Factory {
Factory