+ *
+ * @author Petr Bouda
+ */
+class ClassBean extends JerseyBean {
+
+ private final ClassBinding binding;
+ private InjectionTarget injectionTarget;
+
+ /**
+ * Creates a new Jersey-specific {@link javax.enterprise.inject.spi.Bean} instance.
+ * @param runtimeType {@link RuntimeType} type information of the bean source.
+ * @param binding the binding information.
+ */
+ ClassBean(RuntimeType runtimeType, ClassBinding binding) {
+ super(runtimeType, binding);
+ this.binding = binding;
+ }
+
+ @Override
+ public Class extends Annotation> getScope() {
+ /*
+ * Resource class without the Scope annotation should registered as a RequestScoped.
+ */
+ if (binding.getScope() == null && BeanHelper.isResourceClass(binding.getService())) {
+ return RequestScoped.class;
+ }
+
+ return binding.getScope() == null ? Dependent.class : transformScope(binding.getScope());
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public T create(CreationalContext context) {
+ T instance = injectionTarget.produce(context);
+ injectionTarget.inject(instance, context);
+ injectionTarget.postConstruct(instance);
+ return instance;
+ }
+
+ @Override
+ public void destroy(T instance, CreationalContext context) {
+ injectionTarget.preDestroy(instance);
+ injectionTarget.dispose(instance);
+ context.release();
+ }
+
+ @Override
+ public Set getTypes() {
+ Set contracts = super.getTypes();
+ contracts.addAll(Arrays.asList(binding.getService().getInterfaces()));
+ return contracts;
+ }
+
+ @Override
+ public Class> getBeanClass() {
+ return binding.getService();
+ }
+
+ @Override
+ public Set getInjectionPoints() {
+ return injectionTarget.getInjectionPoints();
+ }
+
+ /**
+ * Lazy set of an injection target because to create fully functional injection target needs already created bean.
+ *
+ * @param injectionTarget {@link javax.enterprise.context.spi.Contextual} information belonging to this bean.
+ */
+ void setInjectionTarget(InjectionTarget injectionTarget) {
+ this.injectionTarget = injectionTarget;
+ }
+
+ @Override
+ public String toString() {
+ return "ClassBean{" + getBeanClass() + "(" + getRutimeType() + ")}";
+ }
+
+ public InjectionTarget getInjectionTarget() {
+ return injectionTarget;
+ }
+}
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableInstanceBean.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableInstanceBean.java
new file mode 100644
index 0000000000..f319a4f34d
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableInstanceBean.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+package org.glassfish.jersey.inject.weld.internal.bean;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.InjectionTarget;
+import javax.ws.rs.RuntimeType;
+
+import org.glassfish.jersey.inject.weld.internal.inject.InitializableInstanceBinding;
+import org.glassfish.jersey.inject.weld.internal.injector.JerseyClientCreationalContext;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Instance bean to be created in the pre-initialization phase and initialized after Jersey is bootstrap.
+ * @param the class of the bean instance.
+ */
+public class InitializableInstanceBean extends JerseyBean {
+
+ private InjectionTarget injectionTarget;
+
+ /**
+ * Creates a new Jersey-specific {@link javax.enterprise.inject.spi.Bean} instance.
+ *
+ * @param binding {@link javax.enterprise.inject.spi.BeanAttributes} part of the bean.
+ */
+ InitializableInstanceBean(RuntimeType runtimeType, InitializableInstanceBinding binding) {
+ super(runtimeType, binding);
+ }
+
+ @Override
+ public Class extends Annotation> getScope() {
+ return getBinding().getScope() == null ? Dependent.class : transformScope(getBinding().getScope());
+ }
+
+ @Override
+ public T create(CreationalContext context) {
+ InitializableInstanceBinding realBinding = (InitializableInstanceBinding) getBinding();
+ if (JerseyClientCreationalContext.class.isInstance(context)) {
+ realBinding = ((JerseyClientCreationalContext) context).getInjectionManager().getInjectionManagerBinding(realBinding);
+ }
+ T service = realBinding.getService();
+ this.injectionTarget.inject(service, context);
+ return service;
+ }
+
+ @Override
+ public Class> getBeanClass() {
+ final InitializableInstanceBinding binding = (InitializableInstanceBinding) getBinding();
+ return binding.isInit() ? binding.getImplementationType() : Object.class;
+ }
+
+ /**
+ * Lazy set of an injection target because to create fully functional injection target needs already created bean.
+ *
+ * @param injectionTarget {@link javax.enterprise.context.spi.Contextual} information belonging to this bean.
+ */
+ void setInjectionTarget(InjectionTarget injectionTarget) {
+ this.injectionTarget = injectionTarget;
+ }
+
+ @Override
+ public String toString() {
+ return "InitializableInstanceBean{" + getBeanClass() + "}";
+ }
+}
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableSupplierInstanceBean.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableSupplierInstanceBean.java
new file mode 100644
index 0000000000..cbaaf0cd94
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableSupplierInstanceBean.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.inject.weld.internal.bean;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.ws.rs.RuntimeType;
+
+import org.glassfish.jersey.inject.weld.internal.inject.InitializableSupplierInstanceBinding;
+import org.glassfish.jersey.inject.weld.internal.injector.JerseyClientCreationalContext;
+import org.glassfish.jersey.inject.weld.internal.injector.JerseyInjectionTarget;
+import org.glassfish.jersey.inject.weld.internal.type.ParameterizedTypeImpl;
+import org.glassfish.jersey.internal.inject.DisposableSupplier;
+import org.glassfish.jersey.internal.inject.SupplierInstanceBinding;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.function.Supplier;
+
+/**
+ * Creates an implementation of {@link javax.enterprise.inject.spi.Bean} interface using Jersey's {@link SupplierInstanceBinding}.
+ * Binding provides the information about the bean also called {@link javax.enterprise.inject.spi.BeanAttributes} information.
+ * The {@code Bean} does not use {@link JerseyInjectionTarget} because serves already
+ * created supplier instance, therefore the create operation just return provided instance without any other contextual operation
+ * (produce, inject, destroy). Client has to manage the instance alone.
+ *
+ *
+ * @author Petr Bouda
+ */
+class InitializableSupplierInstanceBean extends JerseyBean> {
+
+ private final Set contracts = new HashSet<>();
+ private final Supplier supplier;
+
+ /**
+ * Creates a new Jersey-specific {@link javax.enterprise.inject.spi.Bean} instance.
+ *
+ * @param binding {@link javax.enterprise.inject.spi.BeanAttributes} part of the bean.
+ */
+ InitializableSupplierInstanceBean(RuntimeType runtimeType, InitializableSupplierInstanceBinding binding) {
+ super(runtimeType, binding);
+ this.supplier = binding.getSupplier();
+
+ for (Type contract: binding.getContracts()) {
+ this.contracts.add(new ParameterizedTypeImpl(Supplier.class, contract));
+ if (DisposableSupplier.class.isAssignableFrom(binding.getSupplier().getClass())) {
+ this.contracts.add(new ParameterizedTypeImpl(DisposableSupplier.class, contract));
+ }
+ }
+ }
+
+ @Override
+ public Set getTypes() {
+ return contracts;
+ }
+
+ @Override
+ public Set getQualifiers() {
+ return DEFAULT_QUALIFIERS;
+ }
+
+ @Override
+ public Supplier create(CreationalContext> context) {
+ if (JerseyClientCreationalContext.class.isInstance(context)) {
+ final InitializableSupplierInstanceBinding binding = (InitializableSupplierInstanceBinding) getBinding();
+ final JerseyClientCreationalContext jerseyContext = (JerseyClientCreationalContext) context;
+ return jerseyContext.getInjectionManager().getInjectionManagerBinding(binding).getSupplier();
+ } else {
+ return supplier;
+ }
+ }
+
+ @Override
+ public Class> getBeanClass() {
+ final InitializableSupplierInstanceBinding binding = (InitializableSupplierInstanceBinding) getBinding();
+ return binding.isInit() ? binding.getOriginalSupplier().getClass() : Object.class;
+ }
+
+ @Override
+ public Class extends Annotation> getScope() {
+ return getBinding().getScope() == null ? Dependent.class : transformScope(getBinding().getScope());
+ }
+}
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableSupplierInstanceBeanBridge.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableSupplierInstanceBeanBridge.java
new file mode 100644
index 0000000000..c86d44f5c1
--- /dev/null
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/InitializableSupplierInstanceBeanBridge.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.inject.weld.internal.bean;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.ws.rs.RuntimeType;
+
+import org.glassfish.jersey.inject.weld.internal.inject.InitializableSupplierInstanceBinding;
+import org.glassfish.jersey.inject.weld.internal.injector.JerseyInjectionTarget;
+import org.glassfish.jersey.internal.inject.DisposableSupplier;
+import org.glassfish.jersey.internal.inject.SupplierInstanceBinding;
+
+import java.lang.annotation.Annotation;
+import java.util.function.Supplier;
+
+/**
+ * Creates an implementation of {@link javax.enterprise.inject.spi.Bean} interface using Jersey's {@link SupplierInstanceBinding}.
+ * Binding provides the information about the bean also called {@link javax.enterprise.inject.spi.BeanAttributes} information.
+ * The {@code Bean} does not use {@link JerseyInjectionTarget} because serves already
+ * created instances, therefore the create operation just return provided instance without any other contextual operation
+ * (produce, inject, destroy). Client has to manage the instance alone.
+ *
+ * This implementation works as bridge between {@link Supplier} and its provided value. This solves the case when the concrete
+ * type of supplier value is fetched from {@link org.glassfish.jersey.internal.inject.InjectionManager} then this
+ * {@link javax.enterprise.inject.spi.Bean} implementation just invokes {@link Supplier#get} method on underlying/registered
+ * supplier.
+ *