Spring BeanFactory 接口

[[Spring IOC 源码学习总笔记]]

BeanFactory 的子接口

Spring BeanFactory 的设计, 基于接口隔离原则(Interface Segregation Principle), 将具有不同细分的功能定义为接口, 增加扩展性, 支持不同功能的 BeanFactory 再实现其接口即可

上图:
image

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 根据类型 获取获取 查找 bean
  • getBeanNamesForAnnotation 获取被注解修饰过的 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 为例:

image

三级缓存 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, 不要傻傻分不清

posted @ 2025-11-06 21:15  daidaidaiyu  阅读(5)  评论(0)    收藏  举报