All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.micronaut.context.BeanDefinitionRegistry Maven / Gradle / Ivy

There is a newer version: 4.7.5
Show newest version
/*
 * Copyright 2017-2020 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.context.exceptions.NoSuchBeanException;
import io.micronaut.core.annotation.Experimental;
import io.micronaut.core.type.Argument;
import io.micronaut.core.util.ArgumentUtils;
import io.micronaut.inject.BeanConfiguration;
import io.micronaut.inject.BeanDefinition;
import io.micronaut.inject.BeanDefinitionReference;

import io.micronaut.core.annotation.NonNull;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.inject.ProxyBeanDefinition;

import java.util.Collection;
import java.util.Collections;
import java.util.Objects;
import java.util.Optional;

/**
 * 

Core bean definition registry interface containing methods to find {@link BeanDefinition} instances.

* * @author Graeme Rocher * @since 1.0 */ public interface BeanDefinitionRegistry { /** * Return whether the bean of the given type is contained within this context. * * @param beanType The bean type * @param qualifier The qualifier for the bean * @param The concrete type * @return True if it is */ boolean containsBean(@NonNull Class beanType, @Nullable Qualifier qualifier); /** * Return whether the bean of the given type is contained within this context. * * @param beanType The bean type * @param qualifier The qualifier for the bean * @param The concrete type * @return True if it is * @since 3.0.0 */ default boolean containsBean(@NonNull Argument beanType, @Nullable Qualifier qualifier) { return containsBean( Objects.requireNonNull(beanType, "Bean type cannot be null").getType(), qualifier ); } /** * Return whether the bean of the given type is contained within this context. * * @param beanType The bean type * @param The concrete type * @return True if it is * @since 3.0.0 */ default boolean containsBean(@NonNull Argument beanType) { return containsBean( Objects.requireNonNull(beanType, "Bean type cannot be null"), null ); } /** * Registers a new reference at runtime. Not that registering beans can impact * the object graph therefore should this should be done as soon as possible prior to * the creation of other beans preferably with a high priority {@link io.micronaut.context.annotation.Context} scope bean. * * @param definition The reference. * @return The registry * @param The bean type * @since 3.6.0 */ @NonNull @Experimental default BeanDefinitionRegistry registerBeanDefinition(@NonNull RuntimeBeanDefinition definition) { throw new UnsupportedOperationException("This implementation of BeanDefinitionRegistry doesn't support runtime registration of bean definitions"); } /** *

Registers a new singleton bean at runtime. This method expects that the bean definition data will have been * compiled ahead of time.

* *

If bean definition data is found the method will perform dependency injection on the instance followed by * invoking any {@link jakarta.annotation.PostConstruct} hooks.

* *

If no bean definition data is found the bean is registered as is.

* * @param type The bean type * @param singleton The singleton bean * @param qualifier The bean qualifier * @param inject Whether the singleton should be injected (defaults to true) * @param The concrete type * @return This bean context */ @NonNull BeanDefinitionRegistry registerSingleton( @NonNull Class type, @NonNull T singleton, @Nullable Qualifier qualifier, boolean inject ); /** * Obtain a bean configuration by name. * * @param configurationName The configuration name * @return An optional with the configuration either present or not */ @NonNull Optional findBeanConfiguration(@NonNull String configurationName); /** * Obtain a {@link BeanDefinition} for the given type. * * @param beanType The type * @param qualifier The qualifier * @param The concrete type * @return An {@link Optional} of the bean definition * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type */ @NonNull Optional> findBeanDefinition(@NonNull Class beanType, @Nullable Qualifier qualifier); /** * Obtain a {@link BeanDefinition} for the given type. * * @param beanType The potentially parameterized type * @param qualifier The qualifier * @param The concrete type * @return An {@link Optional} of the bean definition * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type * @since 3.0.0 */ default @NonNull Optional> findBeanDefinition(@NonNull Argument beanType, @Nullable Qualifier qualifier) { return findBeanDefinition( Objects.requireNonNull(beanType, "Bean type cannot be null").getType(), qualifier ); } /** * Obtain a {@link BeanDefinition} for the given type. * * @param beanType The potentially parameterized type * @param The concrete type * @return An {@link Optional} of the bean definition * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type * @since 3.0.0 */ default @NonNull Optional> findBeanDefinition(@NonNull Argument beanType) { return findBeanDefinition(beanType, null); } /** * Obtain a {@link BeanRegistration} for the given bean. * * @param bean The bean * @param The concrete type * @return An {@link Optional} of the bean definition * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type */ @NonNull Optional> findBeanRegistration(@NonNull T bean); /** * Obtain a {@link BeanDefinition} for the given bean. * * @param bean The bean * @param The concrete type * @return An {@link Optional} of the bean definition * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type * @since 4.3.0 */ @NonNull default Optional> findBeanDefinition(@NonNull T bean) { return findBeanRegistration(bean).map(BeanRegistration::getBeanDefinition); } /** * Obtain a {@link BeanDefinition} for the given type. * * @param beanType The type * @param The concrete type * @return An {@link Optional} of the bean definition * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type */ @NonNull Collection> getBeanDefinitions(@NonNull Class beanType); /** * Obtain a {@link BeanDefinition} for the given type. * * @param beanType The type * @param The concrete type * @return An {@link Optional} of the bean definition * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible * bean definitions exist for the given type * @since 3.0.0 */ default @NonNull Collection> getBeanDefinitions(@NonNull Argument beanType) { Objects.requireNonNull(beanType, "Bean type cannot be null"); return getBeanDefinitions(beanType.getType(), null); } /** * Obtain a {@link BeanDefinition} for the given type. * * @param beanType The type * @param qualifier The qualifier * @param The concrete type * @return An {@link Optional} of the bean definition * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type */ @NonNull Collection> getBeanDefinitions(@NonNull Class beanType, @Nullable Qualifier qualifier); /** * Obtain a {@link BeanDefinition} for the given type. * * @param beanType The type * @param qualifier The qualifier * @param The concrete type * @return An {@link Optional} of the bean definition * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible * bean definitions exist for the given type * @since 3.0.0 */ default @NonNull Collection> getBeanDefinitions(@NonNull Argument beanType, @Nullable Qualifier qualifier) { Objects.requireNonNull(beanType, "Bean type cannot be null"); return getBeanDefinitions(beanType.getType(), qualifier); } /** * Get all of the {@link BeanDefinition} for the given qualifier. * * @param qualifier The qualifier * @return The bean definitions */ @NonNull Collection> getBeanDefinitions(@NonNull Qualifier qualifier); /** * Get all registered {@link BeanDefinition}. * * @return The bean definitions */ @NonNull Collection> getAllBeanDefinitions(); /** * Get all enabled {@link BeanDefinitionReference}. * * @return The bean definitions */ @NonNull Collection> getBeanDefinitionReferences(); /** * Get all disabled {@link DisabledBean}. * * @return The disabled bean definitions * @since 4.0.0 */ default @NonNull Collection> getDisabledBeans() { return Collections.emptyList(); } /** * Find active {@link jakarta.inject.Singleton} beans for the given qualifier. Note that * this method can return multiple registrations for a given singleton bean instance since each bean may have multiple qualifiers. * * @param qualifier The qualifier * @return The beans */ @NonNull Collection> getActiveBeanRegistrations(@NonNull Qualifier qualifier); /** * Find active {@link jakarta.inject.Singleton} beans for the given bean type. Note that * this method can return multiple registrations for a given singleton bean instance since each bean may have multiple qualifiers. * * @param beanType The bean type * @param The concrete type * @return The beans */ @NonNull Collection> getActiveBeanRegistrations(@NonNull Class beanType); /** * Find and if necessary initialize {@link jakarta.inject.Singleton} beans for the given bean type, returning all the active registrations. Note that * this method can return multiple registrations for a given singleton bean instance since each bean may have multiple qualifiers. * * @param beanType The bean type * @param The concrete type * @return The beans */ @NonNull Collection> getBeanRegistrations(@NonNull Class beanType); /** * Find and if necessary initialize {@link jakarta.inject.Singleton} beans for the given bean type, returning all the active registrations. Note that * this method can return multiple registrations for a given singleton bean instance since each bean may have multiple qualifiers. * * @param beanType The bean type * @param qualifier The qualifier * @param The concrete type * @return The beans * @since 2.4.0 */ @NonNull Collection> getBeanRegistrations(@NonNull Class beanType, @Nullable Qualifier qualifier); /** * Find and if necessary initialize {@link jakarta.inject.Singleton} beans for the given bean type, returning all the active registrations. Note that * this method can return multiple registrations for a given singleton bean instance since each bean may have multiple qualifiers. * * @param beanType The bean type * @param qualifier The qualifier * @param The concrete type * @return The beans * @since 3.0.0 */ default @NonNull Collection> getBeanRegistrations(@NonNull Argument beanType, @Nullable Qualifier qualifier) { return getBeanRegistrations( Objects.requireNonNull(beanType, "Bean type cannot be null").getType(), qualifier ); } /** * Find a bean registration for the given bean type and optional qualifier. * * @param beanType The bean type * @param qualifier The qualifier * @param The concrete type * @return The bean registration * @throws NoSuchBeanException if the bean doesn't exist * @since 2.4.0 */ @NonNull BeanRegistration getBeanRegistration(@NonNull Class beanType, @Nullable Qualifier qualifier); /** * Find a bean registration for the given bean type and optional qualifier. * * @param beanType The potentially parameterized bean type * @param qualifier The qualifier * @param The concrete type * @return The bean registration * @throws NoSuchBeanException if the bean doesn't exist * @since 3.0.0 */ default @NonNull BeanRegistration getBeanRegistration(@NonNull Argument beanType, @Nullable Qualifier qualifier) { return getBeanRegistration( Objects.requireNonNull(beanType, "Bean type cannot be null").getType(), qualifier ); } /** * Find a bean registration for the given bean definition. * * @param beanDefinition The bean definition * @param The concrete type * @return The bean registration * @throws NoSuchBeanException if the bean doesn't exist * @since 3.5.0 */ @NonNull BeanRegistration getBeanRegistration(@NonNull BeanDefinition beanDefinition); /** * Obtain the original {@link BeanDefinition} for a {@link io.micronaut.inject.ProxyBeanDefinition}. * * @param beanType The type * @param qualifier The qualifier * @param The concrete type * @return An {@link Optional} of the bean definition * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type */ @NonNull Optional> findProxyTargetBeanDefinition(@NonNull Class beanType, @Nullable Qualifier qualifier); /** * Obtain the original {@link BeanDefinition} for a {@link io.micronaut.inject.ProxyBeanDefinition}. * * @param beanType The type * @param qualifier The qualifier * @param The concrete type * @return An {@link Optional} of the bean definition * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type */ default @NonNull Optional> findProxyTargetBeanDefinition(@NonNull Argument beanType, @Nullable Qualifier qualifier) { Objects.requireNonNull(beanType, "Bean type cannot be null"); return findProxyTargetBeanDefinition( beanType.getType(), qualifier ); } /** * Obtain the original {@link BeanDefinition} for a {@link io.micronaut.inject.ProxyBeanDefinition}. * * @param proxyBeanDefinition The proxy bean definition * @param The concrete type * @return An {@link Optional} of the bean definition * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist for the given type * @since 3.5.0 */ default @NonNull Optional> findProxyTargetBeanDefinition(@NonNull BeanDefinition proxyBeanDefinition) { Objects.requireNonNull(proxyBeanDefinition, "Proxy bean definition cannot be null"); if (proxyBeanDefinition instanceof ProxyBeanDefinition) { Class targetType = ((ProxyBeanDefinition) proxyBeanDefinition).getTargetType(); Qualifier targetQualifier = proxyBeanDefinition.getDeclaredQualifier(); return findProxyTargetBeanDefinition(targetType, targetQualifier); } return Optional.empty(); } /** * Obtain the proxy {@link BeanDefinition} for the bean of type and qualifier. * * @param beanType The type * @param qualifier The qualifier * @param The concrete type * @return An {@link Optional} of the bean definition * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type */ @NonNull Optional> findProxyBeanDefinition(@NonNull Class beanType, @Nullable Qualifier qualifier); /** * Obtain the proxy {@link BeanDefinition} for the bean of type and qualifier. * * @param beanType The type * @param qualifier The qualifier * @param The concrete type * @return An {@link Optional} of the bean definition * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type */ @NonNull Optional> findProxyBeanDefinition(@NonNull Argument beanType, @Nullable Qualifier qualifier); /** *

Registers a new singleton bean at runtime. This method expects that the bean definition data will have been * compiled ahead of time.

* *

If bean definition data is found the method will perform dependency injection on the instance followed by * invoking any {@link jakarta.annotation.PostConstruct} hooks.

* *

If no bean definition data is found the bean is registered as is.

* * @param type The bean type * @param singleton The singleton bean * @param qualifier The bean qualifier * @param The concrete type * @return This bean context */ default @NonNull BeanDefinitionRegistry registerSingleton( @NonNull Class type, @NonNull T singleton, @Nullable Qualifier qualifier ) { return registerSingleton(type, singleton, qualifier, true); } /** *

Registers a new singleton bean at runtime. This method expects that the bean definition data will have been * compiled ahead of time.

* *

If bean definition data is found the method will perform dependency injection on the instance followed by * invoking any {@link jakarta.annotation.PostConstruct} hooks.

* *

If no bean definition data is found the bean is registered as is.

* * @param type the bean type * @param singleton The singleton bean * @param The concrete type * @return This bean context */ default BeanDefinitionRegistry registerSingleton( @NonNull Class type, @NonNull T singleton ) { return registerSingleton(type, singleton, null); } /** * Obtain a {@link BeanDefinition} for the given type. * * @param beanType The type * @param qualifier The qualifier * @param The concrete type * @return The {@link BeanDefinition} * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type * @throws NoSuchBeanException If the bean cannot be found */ default @NonNull BeanDefinition getBeanDefinition(@NonNull Class beanType, @Nullable Qualifier qualifier) { return findBeanDefinition(beanType, qualifier).orElseThrow(() -> new NoSuchBeanException(beanType, qualifier)); } /** * Obtain a {@link BeanDefinition} for the given type. * * @param beanType The potentially parameterized type * @param qualifier The qualifier * @param The concrete type * @return The {@link BeanDefinition} * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type * @throws NoSuchBeanException If the bean cannot be found * @since 3.0. */ default @NonNull BeanDefinition getBeanDefinition(@NonNull Argument beanType, @Nullable Qualifier qualifier) { return findBeanDefinition(beanType, qualifier).orElseThrow(() -> new NoSuchBeanException(beanType, qualifier)); } /** * Obtain the original {@link BeanDefinition} for a {@link io.micronaut.inject.ProxyBeanDefinition}. * * @param beanType The type * @param qualifier The qualifier * @param The concrete type * @return The {@link BeanDefinition} * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type * @throws NoSuchBeanException If the bean cannot be found */ default @NonNull BeanDefinition getProxyTargetBeanDefinition(@NonNull Class beanType, @Nullable Qualifier qualifier) { return findProxyTargetBeanDefinition(beanType, qualifier).orElseThrow(() -> new NoSuchBeanException(beanType, qualifier)); } /** * Obtain the original {@link BeanDefinition} for a {@link io.micronaut.inject.ProxyBeanDefinition}. * * @param beanType The type * @param qualifier The qualifier * @param The concrete type * @return The {@link BeanDefinition} * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type * @throws NoSuchBeanException If the bean cannot be found * @since 3.0.0 */ default @NonNull BeanDefinition getProxyTargetBeanDefinition(@NonNull Argument beanType, @Nullable Qualifier qualifier) { return findProxyTargetBeanDefinition(beanType, qualifier).orElseThrow(() -> new NoSuchBeanException(beanType, qualifier)); } /** * Obtain a {@link BeanDefinition} for the given type. * * @param beanType The type * @param The concrete type * @return The {@link BeanDefinition} * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type * @throws NoSuchBeanException If the bean cannot be found */ default @NonNull BeanDefinition getBeanDefinition(@NonNull Class beanType) { return findBeanDefinition(beanType, null).orElseThrow(() -> new NoSuchBeanException(beanType)); } /** * Obtain a {@link BeanDefinition} for the given type. * * @param beanType The type * @param The concrete type * @return The {@link BeanDefinition} * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type * @throws NoSuchBeanException If the bean cannot be found * @since 3.0.0 */ default @NonNull BeanDefinition getBeanDefinition(@NonNull Argument beanType) { return getBeanDefinition(beanType, null); } /** * Obtain a {@link BeanDefinition} for the given type. * * @param beanType The type * @param The concrete type * @return An {@link Optional} of the bean definition * @throws io.micronaut.context.exceptions.NonUniqueBeanException When multiple possible bean definitions exist * for the given type */ default @NonNull Optional> findBeanDefinition(@NonNull Class beanType) { return findBeanDefinition(beanType, null); } /** *

Registers a new singleton bean at runtime. This method expects that the bean definition data will have been * compiled ahead of time.

* *

If bean definition data is found the method will perform dependency injection on the instance followed by * invoking any {@link jakarta.annotation.PostConstruct} hooks.

* *

If no bean definition data is found the bean is registered as is.

* * @param singleton The singleton bean * @return This bean context */ default @NonNull BeanDefinitionRegistry registerSingleton(@NonNull Object singleton) { ArgumentUtils.requireNonNull("singleton", singleton); Class type = singleton.getClass(); return registerSingleton(type, singleton); } /** *

Registers a new singleton bean at runtime. This method expects that the bean definition data will have been * compiled ahead of time.

* *

If bean definition data is found the method will perform dependency injection on the instance followed by * invoking any {@link jakarta.annotation.PostConstruct} hooks.

* *

If no bean definition data is found the bean is registered as is.

* * @param singleton The singleton bean * @param inject Whether the singleton should be injected (defaults to true) * @return This bean context */ default @NonNull BeanDefinitionRegistry registerSingleton(@NonNull Object singleton, boolean inject) { ArgumentUtils.requireNonNull("singleton", singleton); Class type = singleton.getClass(); return registerSingleton( type, singleton, null, inject ); } /** * Return whether the bean of the given type is contained within this context. * * @param beanType The bean type * @return True if it is */ @SuppressWarnings("ConstantConditions") default boolean containsBean(@NonNull Class beanType) { return beanType != null && containsBean(beanType, null); } }