Spring BeanFactory 接口
[[Spring IOC 源码学习总笔记]]
BeanFactory 的子接口
Spring BeanFactory 的设计, 基于接口隔离原则(Interface Segregation Principle), 将具有不同细分的功能定义为接口, 增加扩展性, 支持不同功能的 BeanFactory 再实现其接口即可
上图:

HierarchicalBeanFactory
支持层次的BeanFactory, 可以通过getParentBeanFactory()方法获取父级BeanFactory,实现了容器之间的层次关系。
org.springframework.beans.factory.HierarchicalBeanFactory
package org.springframework.beans.factory;
import org.springframework.lang.Nullable;
/**
* Sub-interface implemented by bean factories that can be part
* of a hierarchy.
*
* <p>The corresponding {@code setParentBeanFactory} method for bean
* factories that allow setting the parent in a configurable
* fashion can be found in the ConfigurableBeanFactory interface.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 07.07.2003
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#setParentBeanFactory
*/
public interface HierarchicalBeanFactory extends BeanFactory {
/**
* Return the parent bean factory, or {@code null} if there is none.
*/
@Nullable
BeanFactory getParentBeanFactory();
/**
* Return whether the local bean factory contains a bean of the given name,
* ignoring beans defined in ancestor contexts.
* <p>This is an alternative to {@code containsBean}, ignoring a bean
* of the given name from an ancestor bean factory.
* @param name the name of the bean to query
* @return whether a bean with the given name is defined in the local factory
* @see BeanFactory#containsBean
*/
boolean containsLocalBean(String name);
}
ListableBeanFactory
支持通过名称获取所有的bean定义,而不是只获取一个bean。提供几种遍历查找的方法, 主要是:
getBeanDefinitionNames返回 BeanFactory 定义的所有 bean 名称getBeansOfType根据类型 获取获取 查找 beangetBeanNamesForAnnotation获取被注解修饰过的 bean
in short 它提供可以遍历 查找 bean 的一系列方法, 而不是只能一个一个获取
org.springframework.beans.factory.ListableBeanFactory 部分源码
/**
* Extension of the {@link BeanFactory} interface to be implemented by bean factories
* that can enumerate all their bean instances, rather than attempting bean lookup
* by name one by one as requested by clients. BeanFactory implementations that
* preload all their bean definitions (such as XML-based factories) may implement
* this interface.
*
* <p>If this is a {@link HierarchicalBeanFactory}, the return values will <i>not</i>
* take any BeanFactory hierarchy into account, but will relate only to the beans
* defined in the current factory. Use the {@link BeanFactoryUtils} helper class
* to consider beans in ancestor factories too.
*
* <p>The methods in this interface will just respect bean definitions of this factory.
* They will ignore any singleton beans that have been registered by other means like
* {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}'s
* {@code registerSingleton} method, with the exception of
* {@code getBeanNamesForType} and {@code getBeansOfType} which will check
* such manually registered singletons too. Of course, BeanFactory's {@code getBean}
* does allow transparent access to such special beans as well. However, in typical
* scenarios, all beans will be defined by external bean definitions anyway, so most
* applications don't need to worry about this differentiation.
*
* <p><b>NOTE:</b> With the exception of {@code getBeanDefinitionCount}
* and {@code containsBeanDefinition}, the methods in this interface
* are not designed for frequent invocation. Implementations may be slow.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 16 April 2001
* @see HierarchicalBeanFactory
* @see BeanFactoryUtils
*/
public interface ListableBeanFactory extends BeanFactory {
/**
* Return the names of all beans defined in this factory.
* <p>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
*/
String[] getBeanDefinitionNames();
/**
* 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.
* <p><b>NOTE: This method introspects top-level beans only.</b> It does <i>not</i>
* check nested beans which might match the specified type as well.
* <p>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.
* <p>Does not consider any hierarchy this factory may participate in.
* Use BeanFactoryUtils' {@code beansOfTypeIncludingAncestors}
* to include beans in ancestor factories too.
* <p>Note: Does <i>not</i> ignore singleton beans that have been registered
* by other means than bean definitions.
* <p>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)}.
* <p>The Map returned by this method should always return bean names and
* corresponding bean instances <i>in the order of definition</i> in the
* backend configuration, as far as possible.
* @param type 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
* @since 1.1.2
* @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beansOfTypeIncludingAncestors(ListableBeanFactory, Class)
*/
<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;
/**
* Find all names of beans which are annotated with the supplied {@link Annotation}
* type, without creating corresponding bean instances yet.
* <p>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
* @since 4.0
* @see #getBeansWithAnnotation(Class)
* @see #findAnnotationOnBean(String, Class)
*/
String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
AutowireCapableBeanFactory
支持自动装配。可以通过该接口的方法实现对bean的自动装配,包括构造函数注入、属性注入等。
org.springframework.beans.factory.config.AutowireCapableBeanFactory 部分源码
package org.springframework.beans.factory.config;
import java.util.Set;
import org.springframework.beans.BeansException;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.lang.Nullable;
/**
* Extension of the {@link org.springframework.beans.factory.BeanFactory}
* interface to be implemented by bean factories that are capable of
* autowiring, provided that they want to expose this functionality for
* existing bean instances.
*
* <p>This subinterface of BeanFactory is not meant to be used in normal
* application code: stick to {@link org.springframework.beans.factory.BeanFactory}
* or {@link org.springframework.beans.factory.ListableBeanFactory} for
* typical use cases.
*
* <p>Integration code for other frameworks can leverage this interface to
* wire and populate existing bean instances that Spring does not control
* the lifecycle of. This is particularly useful for WebWork Actions and
* Tapestry Page objects, for example.
*
* <p>Note that this interface is not implemented by
* {@link org.springframework.context.ApplicationContext} facades,
* as it is hardly ever used by application code. That said, it is available
* from an application context too, accessible through ApplicationContext's
* {@link org.springframework.context.ApplicationContext#getAutowireCapableBeanFactory()}
* method.
*
* <p>You may also implement the {@link org.springframework.beans.factory.BeanFactoryAware}
* interface, which exposes the internal BeanFactory even when running in an
* ApplicationContext, to get access to an AutowireCapableBeanFactory:
* simply cast the passed-in BeanFactory to AutowireCapableBeanFactory.
*
* @author Juergen Hoeller
* @since 04.12.2003
* @see org.springframework.beans.factory.BeanFactoryAware
* @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory
* @see org.springframework.context.ApplicationContext#getAutowireCapableBeanFactory()
*/
public interface AutowireCapableBeanFactory extends BeanFactory {
/**
* Constant that indicates no externally defined autowiring. Note that
* BeanFactoryAware etc and annotation-driven injection will still be applied.
* 未定义注入方式?
* @see #autowire
* @see #autowireBeanProperties
*/
int AUTOWIRE_NO = 0;
/**
* Constant that indicates autowiring bean properties by name
* (applying to all bean property setters).
* 通过名称注入
* @see #autowire
* @see #autowireBeanProperties
*/
int AUTOWIRE_BY_NAME = 1;
/**
* Constant that indicates autowiring bean properties by type
* (applying to all bean property setters).
* 通过类型注入
* @see #autowire
* @see #autowireBeanProperties
*/
int AUTOWIRE_BY_TYPE = 2;
/**
* Constant that indicates autowiring the greediest constructor that
* can be satisfied (involves resolving the appropriate constructor).
* @see #autowire
* 通过构造函数注入
*/
int AUTOWIRE_CONSTRUCTOR = 3;
/**
* Constant that indicates determining an appropriate autowire strategy
* through introspection of the bean class.
* @see #autowire
* @deprecated as of Spring 3.0: If you are using mixed autowiring strategies,
* prefer annotation-based autowiring for clearer demarcation of autowiring needs.
* 自动选择
*/
@Deprecated
int AUTOWIRE_AUTODETECT = 4;
/**
* Suffix for the "original instance" convention when initializing an existing
* bean instance: to be appended to the fully-qualified bean class name,
* e.g. "com.mypackage.MyClass.ORIGINAL", in order to enforce the given instance
* to be returned, i.e. no proxies etc.
* @since 5.1
* @see #initializeBean(Object, String)
* @see #applyBeanPostProcessorsBeforeInitialization(Object, String)
* @see #applyBeanPostProcessorsAfterInitialization(Object, String)
*/
String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";
ConfigurableBeanFactory
继承自AutowireCapableBeanFactory接口,提供了配置BeanFactory的方法,如设置类加载器、属性编辑器、BeanPostProcessors等。
org.springframework.beans.factory.config.ConfigurableBeanFactory 的部分源码
package org.springframework.beans.factory.config;
import java.beans.PropertyEditor;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.HierarchicalBeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.metrics.ApplicationStartup;
import org.springframework.lang.Nullable;
import org.springframework.util.StringValueResolver;
/**
* Configuration interface to be implemented by most bean factories. Provides
* facilities to configure a bean factory, in addition to the bean factory
* client methods in the {@link org.springframework.beans.factory.BeanFactory}
* interface.
*
* 继承自`AutowireCapableBeanFactory`接口,提供了配置`BeanFactory`的方法,如设置类加载器、属性编辑器、BeanPostProcessors等。
*
* <p>This bean factory interface is not meant to be used in normal application
* code: Stick to {@link org.springframework.beans.factory.BeanFactory} or
* {@link org.springframework.beans.factory.ListableBeanFactory} for typical
* needs. This extended interface is just meant to allow for framework-internal
* plug'n'play and for special access to bean factory configuration methods.
*
* @author Juergen Hoeller
* @since 03.11.2003
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.beans.factory.ListableBeanFactory
* @see ConfigurableListableBeanFactory
*/
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
/**
* 设置加载bean 的类加载器
* Set the class loader to use for loading bean classes.
* Default is the thread context class loader.
* <p>Note that this class loader will only apply to bean definitions
* that do not carry a resolved bean class yet. This is the case as of
* Spring 2.0 by default: Bean definitions only carry bean class names,
* to be resolved once the factory processes the bean definition.
* @param beanClassLoader the class loader to use,
* or {@code null} to suggest the default class loader
*/
void setBeanClassLoader(@Nullable ClassLoader beanClassLoader);
/**
* 设置解析表达式的 解释器
* Specify the resolution strategy for expressions in bean definition values.
* <p>There is no expression support active in a BeanFactory by default.
* An ApplicationContext will typically set a standard expression strategy
* here, supporting "#{...}" expressions in a Unified EL compatible style.
* @since 3.0
*/
void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver);
/**
* 设置属性类型转换的 转换器
* Specify a {@link ConversionService} to use for converting
* property values, as an alternative to JavaBeans PropertyEditors.
* @since 3.0
*/
void setConversionService(@Nullable ConversionService conversionService);
/**
* 添加 属性编辑器
* 在 属性填充时 会用到的, 见[[Spring 中的属性填充]]
* Add a PropertyEditorRegistrar to be applied to all bean creation processes.
* <p>Such a registrar creates new PropertyEditor instances and registers them
* on the given registry, fresh for each bean creation attempt. This avoids
* the need for synchronization on custom editors; hence, it is generally
* preferable to use this method instead of {@link #registerCustomEditor}.
* @param registrar the PropertyEditorRegistrar to register
*/
void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
/**
* 添加 bean 的前置和后置处理器
* 在 bean 实例化, 填充完属性后会回调的
* Add a new BeanPostProcessor that will get applied to beans created
* by this factory. To be invoked during factory configuration.
* <p>Note: Post-processors submitted here will be applied in the order of
* registration; any ordering semantics expressed through implementing the
* {@link org.springframework.core.Ordered} interface will be ignored. Note
* that autodetected post-processors (e.g. as beans in an ApplicationContext)
* will always be applied after programmatically registered ones.
* @param beanPostProcessor the post-processor to register
*/
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
BeanFactory 的关键属性
以 ClassPathXmlApplicationContext 入口创建的 org.springframework.beans.factory.support.DefaultListableBeanFactory 为例:

三级缓存 Map
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
/** Cache of singleton objects: bean name to bean instance. */
/**
* 一级缓存 这是最终缓存实例的地方,保存完全初始化并准备好的Bean实例。
* 所属: org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#singletonObjects
*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/**
* 二级缓存
* 里面存放的是提早曝光的单例对象,早期对象(earlySingletonObjects)。简而言之 就是刚new出来的对象,可是这个对象还没填充属性
* 所属: org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#singletonFactories
*/
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
/** Cache of early singleton objects: bean name to bean instance. */
/**
* 二级缓存
* 存放早期暴露出来的Bean对象,实例化以后,就把对象放到这个Map中。(Bean可能只经过实例化,属性还未填充)
* 所属: org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#earlySingletonObjects
*/
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
BeanDefinition 和 PropertyEditorRegistrar
/**
* 缓存容器中, 所有Bean的 RootBeanDefinition (RootBeanDefinition 可以理解为是Bean完整的描述元数据)
* 所属 org.springframework.beans.factory.support.AbstractBeanFactory#mergedBeanDefinitions
**/
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
/**
* 存储所有属性编辑的 PropertyEditorRegistry
* 见笔记: 扩展 Bean 属性填充时的逻辑
*/
//org.springframework.beans.factory.support.AbstractBeanFactory#propertyEditorRegistrars
private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet<>(4);
////////////////////// DefaultListableBeanFactory
/**
这个list 存储所有的 bean definition 名称
所属 org.springframework.beans.factory.support.DefaultListableBeanFactory#beanDefinitionNames
*/
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
后置处理器
org.springframework.beans.factory.support.AbstractBeanFactory
/**
* 直接添加在 context 中的 BeanPostProcessor
* 所属 org.springframework.beans.factory.support.AbstractBeanFactory#mergedBeanDefinitions
**/
private final List<BeanPostProcessor> beanPostProcessors = new BeanPostProcessorCacheAwareList();
factoryBean 缓存
org.springframework.beans.factory.support.FactoryBeanRegistrySupport
/**
* 缓存 factoryBeans 的目标对象, 注意是单例bean才会放进去Map
* 所属 org.springframework.beans.factory.support.FactoryBeanRegistrySupport#factoryBeanObjectCache
*/
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);
注意 是FactoryBean 不是 BeanFactory, 不要傻傻分不清

浙公网安备 33010602011771号