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

infra.beans.factory.BeanFactory Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2017 - 2024 the original author or authors.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see [https://www.gnu.org/licenses/]
 */

package infra.beans.factory;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import infra.beans.BeansException;
import infra.beans.factory.config.AutowireCapableBeanFactory;
import infra.beans.factory.config.BeanDefinition;
import infra.beans.factory.config.ConfigurableBeanFactory;
import infra.beans.factory.config.DestructionAwareBeanPostProcessor;
import infra.beans.factory.support.ChildBeanDefinition;
import infra.beans.factory.support.DependencyInjectorProvider;
import infra.beans.factory.support.RootBeanDefinition;
import infra.core.ResolvableType;
import infra.core.annotation.MergedAnnotation;
import infra.lang.Modifiable;
import infra.lang.Nullable;

/**
 * The root interface for accessing a bean container.
 *
 * 

This is the basic client view of a bean container; * further interfaces such as {@link AutowireCapableBeanFactory} and * {@link ConfigurableBeanFactory} are available for specific purposes. * *

This interface is implemented by objects that hold a number of bean definitions, * each uniquely identified by a String name. Depending on the bean definition, * the factory will return either an independent instance of a contained object * (the Prototype design pattern), or a single shared instance (a superior * alternative to the Singleton design pattern, in which the instance is a * singleton in the scope of the factory). Which type of instance will be returned * depends on the bean factory configuration: the API is the same. * further scopes are available depending on the concrete application * context (e.g. "request" and "session" scopes in a web environment). * *

The point of this approach is that the BeanFactory is a central registry * of application components, and centralizes configuration of application * components (no more do individual objects need to read properties files, * for example). See chapters 4 and 11 of "Expert One-on-One J2EE Design and * Development" for a discussion of the benefits of this approach. * *

Note that it is generally better to rely on Dependency Injection * ("push" configuration) to configure application objects through setters * or constructors, rather than use any form of "pull" configuration like a * BeanFactory lookup. Dependency Injection functionality is * implemented using this BeanFactory interface and its subinterfaces. * *

Normally a BeanFactory will load bean definitions stored in a configuration * source (such as an XML document), and use the {@code infra.beans} * package to configure the beans. However, an implementation could simply return * Java objects it creates as necessary directly in Java code. There are no * constraints on how the definitions could be stored: LDAP, RDBMS, XML, * properties file, etc. Implementations are encouraged to support references * amongst beans (Dependency Injection). *

* this interface includes operations like {@code BeanFactory} * *

In contrast to the methods in {@code BeanFactory}, all of the * operations in this interface will also check parent factories if this is a * {@link HierarchicalBeanFactory}. If a bean is not found in this factory instance, * the immediate parent factory will be asked. Beans in this factory instance * are supposed to override beans of the same name in any parent factory. * *

Bean factory implementations should support the standard bean lifecycle interfaces * as far as possible. The full set of initialization methods and their standard order is: *

    *
  1. BeanNameAware's {@code setBeanName} *
  2. BeanClassLoaderAware's {@code setBeanClassLoader} *
  3. BeanFactoryAware's {@code setBeanFactory} *
  4. EnvironmentAware's {@code setEnvironment} *
  5. ResourceLoaderAware's {@code setResourceLoader} * (only applicable when running in an application context) *
  6. ApplicationEventPublisherAware's {@code setApplicationEventPublisher} * (only applicable when running in an application context) *
  7. ApplicationContextAware's {@code setApplicationContext} * (only applicable when running in an application context) *
  8. {@code postProcessBeforeInitialization} methods of BeanPostProcessors *
  9. InitializingBean's {@code afterPropertiesSet} *
  10. a custom {@code init-method} definition *
  11. {@code postProcessAfterInitialization} methods of BeanPostProcessors *
* *

On shutdown of a bean factory, the following lifecycle methods apply: *

    *
  1. {@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors *
  2. DisposableBean's {@code destroy} *
  3. a custom {@code destroy-method} definition *
* * @author Rod Johnson * @author Juergen Hoeller * @author Chris Beams * @author Harry Yang * @see BeanNameAware#setBeanName * @see BeanClassLoaderAware#setBeanClassLoader * @see BeanFactoryAware#setBeanFactory * @see infra.context.EnvironmentAware#setEnvironment * @see infra.context.ResourceLoaderAware#setResourceLoader * @see infra.context.ApplicationEventPublisherAware#setApplicationEventPublisher * @see infra.context.ApplicationContextAware#setApplicationContext * @see InitializationBeanPostProcessor#postProcessBeforeInitialization * @see InitializingBean#afterPropertiesSet * @see BeanDefinition#getInitMethodName() * @see InitializationBeanPostProcessor#postProcessAfterInitialization * @see DestructionAwareBeanPostProcessor#postProcessBeforeDestruction * @see DisposableBean#destroy * @see BeanDefinition#getDestroyMethodName() * @since 2018-06-23 11:22:26 */ public interface BeanFactory extends DependencyInjectorProvider { /** * Used to dereference a {@link FactoryBean} instance and distinguish it from * beans created by the FactoryBean. For example, if the bean named * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject} * will return the factory, not the instance returned by the factory. */ String FACTORY_BEAN_PREFIX = "&"; //--------------------------------------------------------------------- // Get operations for name-lookup //--------------------------------------------------------------------- /** * Return an instance, which may be shared or independent, of the specified bean. *

This method allows a BeanFactory to be used as a replacement for the * Singleton or Prototype design pattern. Callers may retain references to * returned objects in the case of Singleton beans. *

Translates aliases back to the corresponding canonical bean name. *

Will ask the parent factory if the bean cannot be found in this factory instance. * * @param name the name of the bean to retrieve * @return bean instance, returns null if its return from a factory-method * @throws BeansException Exception occurred when getting a named bean * @throws NoSuchBeanDefinitionException if there is no bean with the specified name */ @Nullable Object getBean(String name) throws BeansException; /** * Return an instance, which may be shared or independent, of the specified bean. *

Allows for specifying explicit constructor arguments / factory method arguments, * overriding the specified default arguments (if any) in the bean definition. * * @param name the name of the bean to retrieve * @param args arguments to use when creating a bean instance using explicit arguments * (only applied when creating a new instance as opposed to retrieving an existing one) * @return an instance of the bean, returns null if its return from a factory-method * @throws BeanDefinitionStoreException if arguments have been given but * the affected bean isn't a prototype * @throws BeansException if the bean could not be created * @throws NoSuchBeanDefinitionException if there is no such bean definition * @since 4.0 */ @Nullable Object getBean(String name, Object... args) throws BeansException; /** * Return an instance, which may be shared or independent, of the specified bean. *

Behaves the same as {@link #getBean(String)}, but provides a measure of type * safety by throwing a BeanNotOfRequiredTypeException if the bean is not of the * required type. This means that ClassCastException can't be thrown on casting * the result correctly, as can happen with {@link #getBean(String)}. *

Translates aliases back to the corresponding canonical bean name. *

Will ask the parent factory if the bean cannot be found in this factory instance. * * @param name the name of the bean to retrieve * @param requiredType type the bean must match; can be an interface or superclass * @return an instance of the bean. * Note that the return value will never be {@code null}. In case of a stub for * {@code null} from a factory method having been resolved for the requested bean, a * {@code BeanNotOfRequiredTypeException} against the NullValue stub will be raised. * Consider using {@link #getBeanProvider(Class)} for resolving optional dependencies. * @throws BeanNotOfRequiredTypeException if the bean is not of the required type * @throws BeansException if the bean could not be created * @throws NoSuchBeanDefinitionException if there is no such bean definition */ T getBean(String name, Class requiredType) throws BeansException; /** * Is this bean a shared singleton? That is, will {@link #getBean} always * return the same instance? *

Note: This method returning {@code false} does not clearly indicate * independent instances. It indicates non-singleton instances, which may correspond * to a scoped bean as well. Use the {@link #isPrototype} operation to explicitly * check for independent instances. *

Translates aliases back to the corresponding canonical bean name. *

Will ask the parent factory if the bean cannot be found in this factory instance. * * @param name the name of the bean to query * @return whether this bean corresponds to a singleton instance * @throws NoSuchBeanDefinitionException if there is no bean with the given name * @see #getBean * @see #isPrototype */ boolean isSingleton(String name) throws NoSuchBeanDefinitionException; /** * Is this bean a prototype? That is, will {@link #getBean} always return * independent instances? *

Note: This method returning {@code false} does not clearly indicate * a singleton object. It indicates non-independent instances, which may correspond * to a scoped bean as well. Use the {@link #isSingleton} operation to explicitly * check for a shared singleton instance. *

Translates aliases back to the corresponding canonical bean name. *

Will ask the parent factory if the bean cannot be found in this factory instance. * * @param name the name of the bean to query * @return whether this bean will always deliver independent instances * @throws NoSuchBeanDefinitionException if there is no bean with the given name * @see #getBean * @see #isSingleton */ boolean isPrototype(String name) throws NoSuchBeanDefinitionException; /** * Determine the type of the bean with the given name. More specifically, * determine the type of object that {@link #getBean} would return for the given name. *

For a {@link FactoryBean}, return the type of object that the FactoryBean creates, * as exposed by {@link FactoryBean#getObjectType()}. This may lead to the initialization * of a previously uninitialized {@code FactoryBean} (see {@link #getType(String, boolean)}). *

Translates aliases back to the corresponding canonical bean name. *

Will ask the parent factory if the bean cannot be found in this factory instance. * * @param name the name of the bean to query * @return the type of the bean, or {@code null} if not determinable * @throws NoSuchBeanDefinitionException if there is no bean with the given name * @see #getBean * @see #isTypeMatch */ @Nullable Class getType(String name) throws NoSuchBeanDefinitionException; /** * Determine the type of the bean with the given name. More specifically, * determine the type of object that {@link #getBean} would return for the given name. *

For a {@link FactoryBean}, return the type of object that the FactoryBean creates, * as exposed by {@link FactoryBean#getObjectType()}. Depending on the * {@code allowFactoryBeanInit} flag, this may lead to the initialization of a previously * uninitialized {@code FactoryBean} if no early type information is available. *

Translates aliases back to the corresponding canonical bean name. *

Will ask the parent factory if the bean cannot be found in this factory instance. * * @param name the name of the bean to query * @param allowFactoryBeanInit whether a {@code FactoryBean} may get initialized * just for the purpose of determining its object type * @return the type of the bean, or {@code null} if not determinable * @throws NoSuchBeanDefinitionException if there is no bean with the given name * @see #getBean * @see #isTypeMatch * @since 4.0 */ @Nullable Class getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException; /** * Find an {@link Annotation} of {@code annotationType} on the specified bean, * checking the bean's factory method if no annotation can be found traversing its * interfaces and super classes(if any). *

* Synthesize MergedAnnotation into Annotation *

* * @param beanName the name of the bean to look for annotations on * @param annotationType the type of annotation to look for * (at class, interface or factory method level of the specified bean) * @return the annotation of the given type if found, or {@code null} otherwise * @throws NoSuchBeanDefinitionException if there is no bean with the given name * @see #getAnnotatedBeans * @since 3.0 */ @Nullable A findSynthesizedAnnotation(String beanName, Class annotationType) throws NoSuchBeanDefinitionException; /** * Find an {@link MergedAnnotation} of {@code annotationType} on the specified bean, * checking the bean's factory method if no annotation can be found traversing its * interfaces and super classes(if any). * * @param beanName the name of the bean to look for annotations on * @param annotationType the type of annotation to look for * (at class, interface or factory method level of the specified bean) * @return the annotation of the given type if found, or {@code null} otherwise * @throws NoSuchBeanDefinitionException if there is no bean with the given name * @see #getBeanNamesForAnnotation * @see #getBeansWithAnnotation * @see #getType(String) * @since 3.0 */ MergedAnnotation findAnnotationOnBean(String beanName, Class annotationType) throws NoSuchBeanDefinitionException; /** * Find an {@link MergedAnnotation} of {@code annotationType} on the specified bean, * checking the bean's factory method if no annotation can be found traversing its * interfaces and super classes(if any). * * @param beanName the name of the bean to look for annotations on * @param annotationType the type of annotation to look for * (at class, interface or factory method level of the specified bean) * @param allowFactoryBeanInit whether a {@code FactoryBean} may get initialized * just for the purpose of determining its object type * @return the annotation of the given type if found, or {@link MergedAnnotation#missing()} otherwise * @throws NoSuchBeanDefinitionException if there is no bean with the given name * @see #getBeanNamesForAnnotation * @see #getBeansWithAnnotation * @see #getType(String, boolean) * @since 4.0 */ MergedAnnotation findAnnotationOnBean(String beanName, Class annotationType, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException; /** * Find all {@link Annotation} instances of {@code annotationType} on the specified * bean, traversing its interfaces and superclasses if no annotation can be found on * the given class itself, as well as checking the bean's factory method (if any). * * @param beanName the name of the bean to look for annotations on * @param annotationType the type of annotation to look for * (at class, interface or factory method level of the specified bean) * @param allowFactoryBeanInit whether a {@code FactoryBean} may get initialized * just for the purpose of determining its object type * @return the set of annotations of the given type found (potentially empty) * @throws NoSuchBeanDefinitionException if there is no bean with the given name * @see #getBeanNamesForAnnotation(Class) * @see #findAnnotationOnBean(String, Class, boolean) * @see #getType(String, boolean) * @since 4.0 */ @Modifiable Set findAllAnnotationsOnBean(String beanName, Class annotationType, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException; /** * Does this bean factory contain a bean definition or externally registered singleton * instance with the given name? *

If the given name is an alias, it will be translated back to the corresponding * canonical bean name. *

If this factory is hierarchical, will ask any parent factory if the bean cannot * be found in this factory instance. *

If a bean definition or singleton instance matching the given name is found, * this method will return {@code true} whether the named bean definition is concrete * or abstract, lazy or eager, in scope or not. Therefore, note that a {@code true} * return value from this method does not necessarily indicate that {@link #getBean} * will be able to obtain an instance for the same name. * * @param name the name of the bean to query * @return whether a bean with the given name is present * @since 4.0 */ boolean containsBean(String name); /** * Check if this bean factory contains a bean definition with the given name. *

Does not consider any hierarchy this factory may participate in, * and ignores any singleton beans that have been registered by * other means than bean definitions. * * @param beanName the name of the bean to look for * @return if this bean factory contains a bean definition with the given name * @see #containsBean(String) * @since 4.0 */ boolean containsBeanDefinition(String beanName); /** * Check whether the bean with the given name matches the specified type. * More specifically, check whether a {@link #getBean} call for the given name * would return an object that is assignable to the specified target type. *

Translates aliases back to the corresponding canonical bean name. *

Will ask the parent factory if the bean cannot be found in this factory instance. * * @param name the name of the bean to query * @param typeToMatch the type to match against (as a {@code ResolvableType}) * @return {@code true} if the bean type matches, * {@code false} if it doesn't match or cannot be determined yet * @throws NoSuchBeanDefinitionException if there is no bean with the given name * @see #getBean * @see #getType * @since 4.0 */ boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException; /** * Check whether the bean with the given name matches the specified type. * More specifically, check whether a {@link #getBean} call for the given name * would return an object that is assignable to the specified target type. *

Translates aliases back to the corresponding canonical bean name. *

Will ask the parent factory if the bean cannot be found in this factory instance. * * @param name the name of the bean to query * @param typeToMatch the type to match against (as a {@code Class}) * @return {@code true} if the bean type matches, * {@code false} if it doesn't match or cannot be determined yet * @throws NoSuchBeanDefinitionException if there is no bean with the given name * @see #getBean * @see #getType * @since 4.0 */ boolean isTypeMatch(String name, Class typeToMatch) throws NoSuchBeanDefinitionException; /** * Return the bean definition for the given bean name. * Subclasses should normally implement caching, as this method is invoked * by this class every time bean definition metadata is needed. *

Depending on the nature of the concrete bean factory implementation, * this operation might be expensive (for example, because of directory lookups * in external registries). However, for listable bean factories, this usually * just amounts to a local hash lookup: The operation is therefore part of the * public interface there. The same implementation can serve for both this * template method and the public interface method in that case. * * @param beanName the name of the bean to find a definition for * @return the BeanDefinition for this prototype name (never {@code null}) * @throws NoSuchBeanDefinitionException if the bean definition cannot be resolved * @throws BeansException in case of errors * @see RootBeanDefinition * @see ChildBeanDefinition * @see ConfigurableBeanFactory#getBeanDefinition */ BeanDefinition getBeanDefinition(String beanName) throws BeansException; //--------------------------------------------------------------------- // Listing Get operations for type-lookup //--------------------------------------------------------------------- /** * Return the bean instance that uniquely matches the given object type, if any. *

This method goes into {@link BeanFactory} by-type lookup territory * but may also be translated into a conventional by-name lookup based on the name * of the given type. For more extensive retrieval operations across sets of beans, * use {@link BeanFactory} and/or {@link BeanFactoryUtils}. * * @param requiredType type the bean must match; can be an interface or superclass * @return an instance of the single bean matching the required type * @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found * @throws BeansException if the bean could not be created * @throws NoSuchBeanDefinitionException if no bean of the given type was found * @since 3.0 */ T getBean(Class requiredType) throws BeansException; /** * Return an instance, which may be shared or independent, of the specified bean. *

Allows for specifying explicit constructor arguments / factory method arguments, * overriding the specified default arguments (if any) in the bean definition. *

This method goes into {@link BeanFactory} by-type lookup territory * but may also be translated into a conventional by-name lookup based on the name * of the given type. For more extensive retrieval operations across sets of beans, * use {@link BeanFactory} and/or {@link BeanFactoryUtils}. * * @param requiredType type the bean must match; can be an interface or superclass * @param args arguments to use when creating a bean instance using explicit arguments * (only applied when creating a new instance as opposed to retrieving an existing one) * @return an instance of the bean, returns null if its return from a factory-method. * @throws BeanDefinitionStoreException if arguments have been given but * the affected bean isn't a prototype * @throws NoSuchBeanDefinitionException if there is no such bean definition * @throws BeansException if the bean could not be created * @since 4.0 */ T getBean(Class requiredType, Object... args) throws BeansException; /** * Find all beans which are annotated with the supplied {@link Annotation} type, * returning a List of bean instances. *

Note that this method considers objects created by FactoryBeans, which means * that FactoryBeans will get initialized in order to determine their object type. * * @param annotationType the type of annotation to look for * (at class, interface or factory method level of the specified bean) * @return a List with the matching beans, containing the bean names as * keys and the corresponding bean instances as values, never be {@code null} * @throws BeansException if a bean could not be created * @see #findSynthesizedAnnotation * @since 3.0 */ @Modifiable @SuppressWarnings("unchecked") default List getAnnotatedBeans(Class annotationType) throws BeansException { return (List) new ArrayList<>(getBeansWithAnnotation(annotationType).values()); } /** * Find all beans which are annotated with the supplied {@link Annotation} type, * returning a Map of bean names with corresponding bean instances. *

Note that this method considers objects created by FactoryBeans, which means * that FactoryBeans will get initialized in order to determine their object type. * * @param annotationType the type of annotation to look for * (at class, interface or factory method level of the specified bean) * @return a Map with the matching beans, containing the bean names as * keys and the corresponding bean instances as values, never be {@code null} * @throws BeansException if a bean could not be created * @see #findSynthesizedAnnotation * @since 3.0 */ @Modifiable default Map getBeansWithAnnotation(Class annotationType) throws BeansException { return getBeansWithAnnotation(annotationType, true); } /** * Find all beans which are annotated with the supplied {@link Annotation} type, * returning a Map of bean names with corresponding bean instances. *

Note that this method considers objects created by FactoryBeans, which means * that FactoryBeans will get initialized in order to determine their object type. * * @param annotationType the type of annotation to look for * (at class, interface or factory method level of the specified bean) * @param includeNonSingletons whether to include prototype or scoped beans too * or just singletons (also applies to FactoryBeans) * @return a Map with the matching beans, containing the bean names as * keys and the corresponding bean instances as values, never be {@code null} * @throws BeansException if a bean could not be created * @see #findSynthesizedAnnotation * @since 3.0 */ @Modifiable Map getBeansWithAnnotation(Class annotationType, boolean includeNonSingletons) throws BeansException; /** * Get a set of beans with given type * * @param requiredType Given bean type * @return A set of beans with given type, never be {@code null} * @since 2.1.2 */ @Modifiable default List getBeans(Class requiredType) { return new ArrayList<>(getBeansOfType(requiredType).values()); } /** * Return the bean instances that match the given object type (including * subclasses), judging from either bean definitions or the value of * {@code getObjectType} in the case of FactoryBeans. *

NOTE: This method introspects top-level beans only. It does not * check nested beans which might match the specified type as well. *

Does consider objects created by FactoryBeans, which means that FactoryBeans * will get initialized. If the object created by the FactoryBean doesn't match, * the raw FactoryBean itself will be matched against the type. *

Does not consider any hierarchy this factory may participate in. * Use BeanFactoryUtils' {@code beansOfTypeIncludingAncestors} * to include beans in ancestor factories too. *

Note: Does not ignore singleton beans that have been registered * by other means than bean definitions. *

This version of getBeansOfType matches all kinds of beans, be it * singletons, prototypes, or FactoryBeans. In most implementations, the * result will be the same as for {@code getBeansOfType(type, true, true)}. *

The Map returned by this method should always return bean names and * corresponding bean instances in the order of definition in the * backend configuration, as far as possible. * * @param requiredType the class or interface to match, or {@code null} for all concrete beans * @return a Map with the matching beans, containing the bean names as * keys and the corresponding bean instances as values * @throws BeansException if a bean could not be created * @see FactoryBean#getObjectType() * @see BeanFactoryUtils#beansOfTypeIncludingAncestors(BeanFactory, Class) * @since 2.1.6 */ @Modifiable default Map getBeansOfType(Class requiredType) { return getBeansOfType(requiredType, true, true); } /** * Return the bean instances that match the given object type (including * subclasses), judging from either bean definitions or the value of * {@code getObjectType} in the case of FactoryBeans. *

NOTE: This method introspects top-level beans only. It does not * check nested beans which might match the specified type as well. *

Does consider objects created by FactoryBeans if the "allowEagerInit" flag is set, * which means that FactoryBeans will get initialized. If the object created by the * FactoryBean doesn't match, the raw FactoryBean itself will be matched against the * type. If "allowEagerInit" is not set, only raw FactoryBeans will be checked * (which doesn't require initialization of each FactoryBean). *

Does not consider any hierarchy this factory may participate in. * Use BeanFactoryUtils' {@code beansOfTypeIncludingAncestors} * to include beans in ancestor factories too. *

Note: Does not ignore singleton beans that have been registered * by other means than bean definitions. *

The Map returned by this method should always return bean names and * corresponding bean instances in the order of definition in the * backend configuration, as far as possible. * * @param type the class or interface to match, or {@code null} for all concrete beans * @param includeNonSingletons whether to include prototype or scoped beans too * or just singletons (also applies to FactoryBeans) * @param allowEagerInit whether to introspect lazy-init singletons * and objects created by FactoryBeans - or by factory methods with a * "factory-bean" reference - for the type check. Note that FactoryBeans need to be * eagerly initialized to determine their type: So be aware that passing in "true" * for this flag will initialize FactoryBeans and "factory-bean" references. Only * actually necessary initialization for type checking purposes will be performed; * constructor and method invocations will still be avoided as far as possible. * @return a Map with the matching beans, containing the bean names as * keys and the corresponding bean instances as values * @throws BeansException if a bean could not be created * @see FactoryBean#getObjectType() * @see BeanFactoryUtils#beansOfTypeIncludingAncestors(BeanFactory, Class, boolean, boolean) * @since 3.0 */ @Modifiable default Map getBeansOfType(@Nullable Class type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException { return getBeansOfType(ResolvableType.forClass(type), includeNonSingletons, allowEagerInit); } /** * Return the bean instances that match the given object type (including * subclasses), judging from either bean definitions or the value of * {@code getBeanClass} in the case of FactoryBeans. *

Note: Does not ignore singleton beans that have been registered * by other means than bean definitions. *

* Get a map of beans with given type *

* * @param requiredType the ResolvableType or interface to match, or {@code null} for all concrete beans * @param includeNonSingletons whether to include prototype or scoped beans too * or just singletons (also applies to FactoryBeans) * @param allowEagerInit whether to introspect lazy-init singletons * and objects created by FactoryBeans - or by factory methods with a * "factory-bean" reference - for the type check. Note that FactoryBeans need to be * eagerly initialized to determine their type: So be aware that passing in "true" * for this flag will initialize FactoryBeans and "factory-bean" references. Only * actually necessary initialization for type checking purposes will be performed; * constructor and method invocations will still be avoided as far as possible. * @param required type * @return a Map with the matching beans, containing the bean names as * keys and the corresponding bean instances as values * @throws BeansException if a bean could not be created * @see FactoryBean#getObjectType * @since 3.0 */ @Modifiable Map getBeansOfType(ResolvableType requiredType, boolean includeNonSingletons, boolean allowEagerInit); // /** * Return the names of beans matching the given type (including subclasses), * judging from either bean definitions or the value of {@code getBeanClass} * in the case of FactoryBeans. * * @param requiredType the class or interface to match, or {@code null} for all bean names * @return the names of beans (or objects created by FactoryBeans) matching * the given object type (including subclasses), or an empty Set if none * @see FactoryBean#getObjectType() * @since 3.0 */ @Modifiable default Set getBeanNamesForType(Class requiredType) { return getBeanNamesForType(requiredType, true); } /** * Return the names of beans matching the given type (including subclasses), * judging from either bean definitions or the value of {@code getBeanClass} * in the case of FactoryBeans. *

* include singletons already in {@code singletons} but not in {@code beanDefinitionMap} *

* * @param requiredType the class or interface to match, or {@code null} for all bean names * @param includeNonSingletons whether to include prototype or scoped beans too * or just singletons (also applies to FactoryBeans) * @return the names of beans (or objects created by FactoryBeans) matching * the given object type (including subclasses), or an empty Set if none * @see FactoryBean#getObjectType() * @since 3.0 */ @Modifiable Set getBeanNamesForType(Class requiredType, boolean includeNonSingletons); /** * Return the names of beans matching the given type (including subclasses), * judging from either bean definitions or the value of {@code getObjectType} * in the case of FactoryBeans. *

NOTE: This method introspects top-level beans only. It does not * check nested beans which might match the specified type as well. *

Does consider objects created by FactoryBeans if the "allowEagerInit" flag is set, * which means that FactoryBeans will get initialized. If the object created by the * FactoryBean doesn't match, the raw FactoryBean itself will be matched against the * type. If "allowEagerInit" is not set, only raw FactoryBeans will be checked * (which doesn't require initialization of each FactoryBean). *

Does not consider any hierarchy this factory may participate in. * Use BeanFactoryUtils' {@code beanNamesForTypeIncludingAncestors} * to include beans in ancestor factories too. *

Note: Does not ignore singleton beans that have been registered * by other means than bean definitions. *

Bean names returned by this method should always return bean names in the * order of definition in the backend configuration, as far as possible. * * @param requiredType the class or interface to match, or {@code null} for all bean names * @param includeNonSingletons whether to include prototype or scoped beans too * or just singletons (also applies to FactoryBeans) * @param allowEagerInit whether to introspect lazy-init singletons * and objects created by FactoryBeans - or by factory methods with a * "factory-bean" reference - for the type check. Note that FactoryBeans need to be * eagerly initialized to determine their type: So be aware that passing in "true" * for this flag will initialize FactoryBeans and "factory-bean" references. Only * actually necessary initialization for type checking purposes will be performed; * constructor and method invocations will still be avoided as far as possible. * @return the names of beans (or objects created by FactoryBeans) matching * the given object type (including subclasses), or an empty Set if none * @see FactoryBean#getObjectType() * @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(BeanFactory, Class, boolean, boolean) * @since 3.0 */ @Modifiable default Set getBeanNamesForType(@Nullable Class requiredType, boolean includeNonSingletons, boolean allowEagerInit) { return getBeanNamesForType(ResolvableType.forClass(requiredType), includeNonSingletons, allowEagerInit); } /** * Return the names of beans matching the given type (including subclasses), * judging from either bean definitions or the value of {@code getObjectType} * in the case of FactoryBeans. *

NOTE: This method introspects top-level beans only. It does not * check nested beans which might match the specified type as well. *

Does consider objects created by FactoryBeans, which means that FactoryBeans * will get initialized. If the object created by the FactoryBean doesn't match, * the raw FactoryBean itself will be matched against the type. *

Does not consider any hierarchy this factory may participate in. * Use BeanFactoryUtils' {@code beanNamesForTypeIncludingAncestors} * to include beans in ancestor factories too. *

Note: Does not ignore singleton beans that have been registered * by other means than bean definitions. *

This version of {@code getBeanNamesForType} matches all kinds of beans, * be it singletons, prototypes, or FactoryBeans. In most implementations, the * result will be the same as for {@code getBeanNamesForType(type, true, true)}. *

Bean names returned by this method should always return bean names in the * order of definition in the backend configuration, as far as possible. * * @param type the generically typed class or interface to match * @return the names of beans (or objects created by FactoryBeans) matching * the given object type (including subclasses), or an empty set if none * @see #isTypeMatch(String, ResolvableType) * @see FactoryBean#getObjectType * @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(BeanFactory, ResolvableType) * @since 4.0 */ @Modifiable Set getBeanNamesForType(ResolvableType type); /** * Return the names of beans matching the given type (including subclasses), * judging from either bean definitions or the value of {@code getObjectType} * in the case of FactoryBeans. *

NOTE: This method introspects top-level beans only. It does not * check nested beans which might match the specified type as well. *

Does consider objects created by FactoryBeans if the "allowEagerInit" flag is set, * which means that FactoryBeans will get initialized. If the object created by the * FactoryBean doesn't match, the raw FactoryBean itself will be matched against the * type. If "allowEagerInit" is not set, only raw FactoryBeans will be checked * (which doesn't require initialization of each FactoryBean). *

Does not consider any hierarchy this factory may participate in. * Use BeanFactoryUtils' {@code beanNamesForTypeIncludingAncestors} * to include beans in ancestor factories too. *

Note: Does not ignore singleton beans that have been registered * by other means than bean definitions. *

Bean names returned by this method should always return bean names in the * order of definition in the backend configuration, as far as possible. * * @param type the generically typed class or interface to match * @param includeNonSingletons whether to include prototype or scoped beans too * or just singletons (also applies to FactoryBeans) * @param allowEagerInit whether to introspect lazy-init singletons * and objects created by FactoryBeans - or by factory methods with a * "factory-bean" reference - for the type check. Note that FactoryBeans need to be * eagerly initialized to determine their type: So be aware that passing in "true" * for this flag will initialize FactoryBeans and "factory-bean" references. Only * actually necessary initialization for type checking purposes will be performed; * constructor and method invocations will still be avoided as far as possible. * @return the names of beans (or objects created by FactoryBeans) matching * the given object type (including subclasses), or an empty array if none * @see FactoryBean#getObjectType() * @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(BeanFactory, ResolvableType, boolean, boolean) * @since 4.0 */ @Modifiable Set getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit); /** * Find all names of beans which are annotated with the supplied {@link Annotation} * type, without creating corresponding bean instances yet. *

Note that this method considers objects created by FactoryBeans, which means * that FactoryBeans will get initialized in order to determine their object type. * * @param annotationType the type of annotation to look for * (at class, interface or factory method level of the specified bean) * @return the names of all matching beans * @see #findSynthesizedAnnotation(String, Class) * @since 4.0 */ @Modifiable Set getBeanNamesForAnnotation(Class annotationType); /** * Return a provider for the specified bean, allowing for lazy on-demand retrieval * of instances, including availability and uniqueness options. *

For matching a generic type, consider {@link #getBeanProvider(ResolvableType)}. * * @param requiredType type the bean must match; can be an interface or superclass * @return a corresponding provider handle * @see #getBeanProvider(ResolvableType) * @since 3.0 */ ObjectProvider getBeanProvider(Class requiredType); /** * Return a provider for the specified bean, allowing for lazy on-demand retrieval * of instances, including availability and uniqueness options. This variant allows * for specifying a generic type to match, similar to reflective injection points * with generic type declarations in method/constructor parameters. *

Note that collections of beans are not supported here, in contrast to reflective * injection points. For programmatically retrieving a list of beans matching a * specific type, specify the actual bean type as an argument here and subsequently * use {@link ObjectProvider#orderedStream()} or its lazy streaming/iteration options. *

Also, generics matching is strict here, as per the Java assignment rules. * For lenient fallback matching with unchecked semantics (similar to the ´unchecked´ * Java compiler warning), consider calling {@link #getBeanProvider(Class)} with the * raw type as a second step if no full generic match is * {@link ObjectProvider#getIfAvailable() available} with this variant. * * @param requiredType type the bean must match; can be a generic type declaration * @return a corresponding provider handle * @see ObjectProvider#iterator() * @see ObjectProvider#stream() * @see ObjectProvider#orderedStream() * @since 4.0 */ ObjectProvider getBeanProvider(ResolvableType requiredType); /** * Return a provider for the specified bean, allowing for lazy on-demand retrieval * of instances, including availability and uniqueness options. * * @param requiredType type the bean must match; can be an interface or superclass * @param allowEagerInit whether stream access may introspect lazy-init singletons * and objects created by FactoryBeans - or by factory methods with a * "factory-bean" reference - for the type check. Note that FactoryBeans need to be * eagerly initialized to determine their type: So be aware that passing in "true" * for this flag will initialize FactoryBeans and "factory-bean" references. Only * actually necessary initialization for type checking purposes will be performed; * constructor and method invocations will still be avoided as far as possible. * @return a corresponding provider handle * @see #getBeanProvider(ResolvableType, boolean) * @see #getBeanProvider(Class) * @see #getBeansOfType(Class, boolean, boolean) * @see #getBeanNamesForType(Class, boolean, boolean) * @since 4.0 */ ObjectProvider getBeanProvider(Class requiredType, boolean allowEagerInit); /** * Return a provider for the specified bean, allowing for lazy on-demand retrieval * of instances, including availability and uniqueness options. * * @param requiredType type the bean must match; can be a generic type declaration. * Note that collection types are not supported here, in contrast to reflective * injection points. For programmatically retrieving a list of beans matching a * specific type, specify the actual bean type as an argument here and subsequently * use {@link ObjectProvider#orderedStream()} or its lazy streaming/iteration options. * @param allowEagerInit whether stream access may introspect lazy-init singletons * and objects created by FactoryBeans - or by factory methods with a * "factory-bean" reference - for the type check. Note that FactoryBeans need to be * eagerly initialized to determine their type: So be aware that passing in "true" * for this flag will initialize FactoryBeans and "factory-bean" references. Only * actually necessary initialization for type checking purposes will be performed; * constructor and method invocations will still be avoided as far as possible. * @return a corresponding provider handle * @see #getBeanProvider(ResolvableType) * @see ObjectProvider#iterator() * @see ObjectProvider#stream() * @see ObjectProvider#orderedStream() * @see #getBeanNamesForType(ResolvableType, boolean, boolean) * @since 4.0 */ ObjectProvider getBeanProvider(ResolvableType requiredType, boolean allowEagerInit); //--------------------------------------------------------------------- // bean-factory stat //--------------------------------------------------------------------- /** * Return the number of beans defined in the factory. *

Does not consider any hierarchy this factory may participate in, * and ignores any singleton beans that have been registered by * other means than bean definitions. * * @return the number of beans defined in the factory * @since 4.0 */ int getBeanDefinitionCount(); /** * Return the names of all beans defined in this factory. *

Does not consider any hierarchy this factory may participate in, * and ignores any singleton beans that have been registered by * other means than bean definitions. * * @return the names of all beans defined in this factory, * or an empty array if none defined * @since 4.0 */ String[] getBeanDefinitionNames(); /** * Return the aliases for the given bean name, if any. *

All of those aliases point to the same bean when used in a {@link #getBean} call. *

If the given name is an alias, the corresponding original bean name * and other aliases (if any) will be returned, with the original bean name * being the first element in the array. *

Will ask the parent factory if the bean cannot be found in this factory instance. * * @param name the bean name to check for aliases * @return the aliases, or an empty array if none * @see #getBean * @since 4.0 */ String[] getAliases(String name); /** * unwrap this BeanFactory to {@code requiredType} * * @throws IllegalArgumentException this bean factory not a requiredType * @since 4.0 */ @SuppressWarnings("unchecked") default T unwrap(Class requiredType) { if (requiredType.isInstance(this)) { return (T) this; } throw new IllegalArgumentException("This BeanFactory '" + this + "' is not a " + requiredType); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy