DefaultListableBeanFactory类层次结构
在开始Bean的实例化和生命周期之前有必要对Bean所处的位置以及相关的类层次结构进行了解。
下图是DefaultListableBeanFactory
的类层次结构
其中有几个比较重要的类或接口需要知道:
DefaultSingletonBeanRegistry
DefaultSingletonBeanRegistry
——默认的单例bean注册器,实现了SingletonBeanRegistry
接口,这个类主要作为BeanFactory
接口实现类的基类。注意,这个类并不关注bean defifinition或bean实例的创造过程,但是这个类维护了很多跟容器相关的Map。这个类的字段如下:
/**
* Internal marker for a null singleton object:
* used as marker value for concurrent Maps (which don't support null values).
*/
protected static final Object NULL_OBJECT = new Object();
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
/** Set of registered singletons, containing the bean names in registration order */
private final Set<String> registeredSingletons = new LinkedHashSet<String>(256);
/** Names of beans that are currently in creation */
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
/** Names of beans currently excluded from in creation checks */
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
/** List of suppressed Exceptions, available for associating related causes */
private Set<Exception> suppressedExceptions;
/** Flag that indicates whether we're currently within destroySingletons */
private boolean singletonsCurrentlyInDestruction = false;
/** Disposable bean instances: bean name --> disposable instance */
private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>();
/** Map between containing bean names: bean name --> Set of bean names that the bean contains */
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16);
/** Map between dependent bean names: bean name --> Set of dependent bean names */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
/** Map between depending bean names: bean name --> Set of bean names for the bean's dependencies */
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
其中包括持有单例bean,工厂bean等实例的map。这个类的其它方法用于操作这几个map或其它字段实现对bean实例的添加、删除等操作。
containedBeanMap用于保存bean在singletonObjects中的key名称到bean的名称集合的映射。
FactoryBeanRegistrySupport
FactoryBeanRegistrySupport
是DefaultSingletonBeanRegistry
的子类,主要添加了对工厂bean注册的支持。
AbstractBeanFactory
这个抽象类是BeanFactory
接口的基本实现,提供ConfigurableBeanFactory
接口的所有实现。这个类通过父类实现对单例bean的管理,在这里BeanFactory
和bean 注册表联系在一起了。AbstractBeanFactory
还提供了原型bean的访问,具体代码如下:
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
这是doGetBean()
方法的一个代码片段,思路就是如果bean是prototype类型,就直接创建一个实例返回。
这里,isPrototype()
方法是BeanDefinition
接口定义的方法。
此时,BeanFactory
和DefaultSingletonBeanRegistry
通过AbstractBeanFactory
联系起来了,通过getBean()
方法(BeanFactory
接口定义)获取bean实例的大致流程是:先解析bean名称获取beanName,检查DefaultSingletonBeanRegistry
注册表中手动注册的单例bean缓存,如果有则返回;没有则根据beanName创建BeanDefinition
实例mbd,通过mbd创建并注册bean实例。注意,创建bean实例时,会先解析并创建bean的依赖,最后创建相应的单例或者原型bean。AbstractBeanFactory
并没有实现createBean()
方法,这个方法由子类具体去实现。
分析到这里,BeanDefinition
, BeanFactory
和DefaultSingletonBeanRegistry
之间并没有交流,只是各自完成相应的工作,比如BeanDefinition
只负责记录bean的定义,BeanFactory
只负责定义容器对bean的基本操作,如获取bean实例,判断bean是单例的还是原型的,DefaultSingletonBeanRegistry
只是一个注册表,它只是简单地提供了一个map用于保存对象的引用。
AbstractAutowireCapableBeanFactory
它提供了createBean()
的默认实现、属性填充、装配(包括自动装配)和初始化。AbstractAutowireCapableBeanFactory
基本上完成了一个容器的所有必要功能,例如bean的实例化、管理bean注册表等。这个类将依赖解析的任务交给子类去实现,以此实现自动装配。
注意,这个类并没有实现bean definition注册表的功能,这个功能是由DefaultListableBeanFactory
实现的。
DefaultListableBeanFactory
一个基于bean definition对象的完全成型的bean factory。典型的使用案例是:在访问bean实例之前,先注册所有的bean definition(可以通过一个bean 定义文件读取)。在本地的bean definition表中,bean definition查询是一项资源消耗较小的操作,主要操作预先构建的bean definition元数据。DefaultListableBeanFactory
是一个标准的bean factory。基于注解的或XML的bean factory要么间接调用了它或者直接继承与它,它们的不同主要在于配置文件的读取方式不同等。至此,在DefaultListableBeanFactory
中知道怎么通过解析bean definition实例化并注册bean,这就是一个容器的基本功能。
Bean的生命周期
bean的生命周期如下图所示:
下面对上述的过程进行详细说明:
- 实例化。Spring对bean的实例化是一个比较复杂的过程。实例化bean的工作是在
AbstractAutowireCapableBeanFactory
类中实现的,其中createBean()
方法或调用doCreateBean()
实现bean的实例化、属性填充以及后置处理器的调用。途中的实例化单纯地指创建bean实例,参考代码。 - 属性填充。Spring将值和bean的引用注入到bean对应的属性中, 参考代码。
- 如果bean实现了
BeanNameAware
接口,Spring将bean的ID传递给setBeanName()
方法。 - 如果bean实现了
BeanFactoryAware
接口,Spring将调用setBeanFactory()
方法,将BeanFactory容器实例传入,这样bean就能感知容器的存在。 - 如果bean实现了
ApplicationContextAware
接口,Spring将调用setApplicationContext()
方法,将bean所在的应用上下文的引用传入,这样bean就能感知应用上下文的存在。 - 如果bean实现了
BeanPostProcessor
接口,Spring将调用它们的postProcessBeforeInitialization()
方法。 - 如果bean实现了
InitializingBean
接口,Spring将调用它们的afterPropertiesSet()
方法。 - 如果bean实现了
BeanPostProcessor
接口,Spring将调用它们的postProcessAfterInitialization()
方法。 - bean准备就绪,并将一直驻留在应用上下文中,直到应用上下文销毁。
- 如果bean实现了
DisposableBean
接口,Spring将调用它的destory()
方法。
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean
// instance.
// 以下方法返回一个bean的代理而不是目标bean的实例,动态代理????
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
// 实例化bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//这个方法完成bean的实例化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 调用后置处理器
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
// bean实例初始化
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String> (dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
总结一下bean实例化的内部实现主要分为以下几步:
- 读取配置文件(.xml)或者通过
@Bean
注解将配置转化成BeanDefinition
,这些BeanDefinition
实例会保存在DefaultListableBeanFactory
的beanDefinitionMap中,bean definition描述了bean在容器中的定义。这时的BeanDefinition
可能只是个半成品,因为某些XML属性配置里会有占位符变量,也可能通过注解注入值,这些变量此时不会被解析出来,需要后续处理。 - 在bean definition 后续处理中,容器首先扫描注册表取出工厂后处理器,对注册表中的
BeanDefinition
进行加工处理,把占位符替换成真正的值,产生成品的BeanDefinition
。 - 通过反射机制扫描
BeanDefinitionRegistry
所有属性编辑器的bean类,并把这些bean放到spring容器的属性编辑器注册表(PropertyEditorRegistry
)中。 - Spring容器从
BeanDefinitionRegistry
中取出加工后的BeanDefinition
,并调用InstantiationStrategy
着手对bean的实例化工作。这里的实例化只是相当于new了一个新对象一样,也就是说,只是跑一个构造函数,不会具体的为属性设置值。 - 实例化的过程中,spring容器使用
BeanWrapper
对bean进行封装,BeanWrapper
结合BeanDefinition
和属性编辑器注册表中的属性编辑器完成bean的属性设置工作。 - 最后调用
BeanPostProcessor
回调函数对bean进行后置处理。