io.micronaut.context.BeanProvider Maven / Gradle / Ivy
/*
* Copyright 2017-2021 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micronaut.context;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.core.type.Argument;
import io.micronaut.inject.BeanDefinition;
import java.util.Collections;
import java.util.Iterator;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/**
* A BeanProvider is a richer replacement for the {@link jakarta.inject.Provider} interface that
* provides additional Micronaut specific methods to assist in programmatic bean creation and discovery.
*
* @param The generic bean type
* @author James Kleeh
* @author graemerocher
* @since 2.4.0
*/
@FunctionalInterface
public interface BeanProvider extends Iterable {
/**
* The get method will materialize an instance of the bean if it is resolvable.
*
* A bean is considered resolvable if it is both unique and present. See {@link #isUnique()} and {@link #isPresent()}.
*
* Note that if the bean is {@link jakarta.inject.Singleton} then multiple calls to this method will return the same instance.
*
* @return A fully-constructed and injected instance of {@link T}.
* @throws io.micronaut.context.exceptions.BeanCreationException If an error occurs during the creation of the bean
* @throws io.micronaut.context.exceptions.NoSuchBeanException if the bean doesn't exist
* @throws io.micronaut.context.exceptions.NonUniqueBeanException if more than one bean matching the current qualifier exists and cannot be resolved unambiguously
*/
@NonNull
T get();
/**
* Finds a bean for the optionally specified qualifier. Return empty if non-exists.
* @param qualifier The qualifier to use. Can be {@code null} which is equivalent to specifying the default qualifier.
* @return An optional of the bean.
* @since 3.2.0
*/
default Optional find(@Nullable Qualifier qualifier) {
if (isPresent()) {
return Optional.of(get());
} else {
return Optional.empty();
}
}
/**
* Obtains a reference to the {@link io.micronaut.inject.BeanDefinition} if the bean is resolvable.
* @return The {@link io.micronaut.inject.BeanDefinition}
* @throws io.micronaut.context.exceptions.NoSuchBeanException if the bean doesn't exist
* @throws io.micronaut.context.exceptions.NonUniqueBeanException if more than one bean matching the current qualifier exists and cannot be resolved unambiguously
* @throws java.lang.UnsupportedOperationException If the BeanProvider was obtained via other means other than dependency injection
* @since 3.2.0
*/
@NonNull
default BeanDefinition getDefinition() {
throw new UnsupportedOperationException("BeanDefinition information can only be obtained from dependency injected providers");
}
/**
* @see #get()
* @param qualifier The qualifier to use, can be {@code null}.
* @return A fully-constructed and injected instance of {@link T}.
* @since 3.0.0
* @throws io.micronaut.context.exceptions.BeanCreationException If an error occurs during the creation of the bean
* @throws io.micronaut.context.exceptions.NoSuchBeanException if the bean doesn't exist
* @throws io.micronaut.context.exceptions.NonUniqueBeanException if more than one bean matching the current qualifier exists and cannot be resolved unambiguously
*/
@NonNull
default T get(@Nullable Qualifier qualifier) {
return get();
}
@NonNull
@Override
default Iterator iterator() {
return Collections.singletonList(get()).iterator();
}
/**
*
* When called, provides back a Stream of the beans available in this provider. If no beans are found, it returns an empty
* stream.
*
*
* @since 3.0.0
* @return a Stream
representing the beans associated with this {@link BeanProvider} object
*/
default Stream stream() {
return StreamSupport.stream(this.spliterator(), false);
}
/**
* Determines if more than one bean matches the specified type and qualifiers.
*
* @since 3.0.0
* @return true
if only one bean matches.
*/
default boolean isUnique() {
return true;
}
/**
* Determines if there is a bean that matches the required type and qualifiers.
*
* @since 3.0.0
* @return true if at least one bean matches.
*/
default boolean isPresent() {
return true;
}
/**
* Is the bean resolvable using the {@link #get()} or {@link #ifPresent(Consumer)} methods.
*
* A bean is said to be resolvable when it is both unique (see {@link #isUnique()}) and present (see {@link #isPresent()})
*
* @return True if the bean is resolvable
* @since 3.0.0
*/
default boolean isResolvable() {
return isUnique() && isPresent();
}
/**
* Executes the given logic if the bean is present. Executes {@link #get()} to obtain the bean which may result in a {@link io.micronaut.context.exceptions.NonUniqueBeanException} if the bean is not unique.
*
* @param consumer the consumer
* @since 3.0.0
* @see #isPresent()
* @throws io.micronaut.context.exceptions.NonUniqueBeanException if the bean is not unique
*/
default void ifPresent(@NonNull Consumer consumer) {
if (isPresent()) {
Objects.requireNonNull(consumer, "Consumer cannot be null")
.accept(get());
}
}
/**
* Executes the given logic if the bean is resolvable. See {@link #isResolvable()}.
*
* @param consumer the consumer
* @since 3.0.0
* @see #isResolvable()
*/
default void ifResolvable(@NonNull Consumer consumer) {
if (isResolvable()) {
Objects.requireNonNull(consumer, "Consumer cannot be null")
.accept(get());
}
}
/**
* Allows selecting an alternative bean if the backing bean is not present.
* @param alternative The alternative, can be {@code null}
* @return The bean if present or else the supplied alternative
* @since 3.0.2
*/
default @Nullable T orElse(@Nullable T alternative) {
if (isPresent()) {
return get();
} else {
return alternative;
}
}
/**
* Create an argument for the given type to aid with bean provider lookup.
*
* @param type The type
* @param The generic type
* @return 3.0.0
*/
@SuppressWarnings({"unchecked", "rawtypes"})
static @NonNull Argument> argumentOf(@NonNull Class type) {
return (Argument) Argument.of(BeanProvider.class, Objects.requireNonNull(type, "Type cannot be null"));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy