Spring源码 - BeanDefinition的加载
重点关注org.springframework.context.support.AbstractApplicationContext#refresh
中调用的
obtainFreshBeanFactory
方法,这个方法也在AbstractApplicationContext中
/**
* Tell the subclass to refresh the internal bean factory.
* @return the fresh BeanFactory instance
* @see #refreshBeanFactory()
* @see #getBeanFactory()
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
注释写的简单,告诉子类来刷新内部的beanFactory,返回被刷新的BeanFactory实例
getBeanFactory
就是返回已经实例化好的beanFactory,比较简单。所以我们重点关注refreshBeanFactory
/**
* This implementation performs an actual refresh of this context's underlying
* bean factory, shutting down the previous bean factory (if any) and
* initializing a fresh bean factory for the next phase of the context's lifecycle.
*/
@Override
protected final void refreshBeanFactory() throws BeansException {
// 既然是刷新,则要检查一下,是否要先销毁已有的Bean和BeanFactory实例
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 创建BeanFactory实例
DefaultListableBeanFactory beanFactory = createBeanFactory();
// 设置唯一序列号ID
beanFactory.setSerializationId(getId());
// 留给子类扩展,对BeanFactory做一些个性化设置
customizeBeanFactory(beanFactory);
// 加载BeanDefinition
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
// 省略
}
}
以上,很清楚的看到创建刷新BeanFactory的几个关键事项:
- 创建BeanFactory实例
createBeanFactory()
- 留给子类扩展,对BeanFactory做一些个性化设置
customizeBeanFactory(beanFactory)
- 加载BeanDefinition
loadBeanDefinitions(beanFactory)
BeanFactory的实例化
先来看BeanFactory的创建
/**
* Create an internal bean factory for this context.
* Called for each {@link #refresh()} attempt.
* <p>The default implementation creates a
* {@link org.springframework.beans.factory.support.DefaultListableBeanFactory}
* with the {@linkplain #getInternalParentBeanFactory() internal bean factory} of this
* context's parent as parent bean factory. Can be overridden in subclasses,
* for example to customize DefaultListableBeanFactory's settings.
* @return the bean factory for this context
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowBeanDefinitionOverriding
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowEagerClassLoading
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowCircularReferences
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowRawInjectionDespiteWrapping
*/
protected DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
注释写的很清楚,为context创建一个beanFactory,因为创建的是DefaultListableBeanFactory
的实例,在下一步customizeBeanFactory(beanFactory)
中,我们就可以调用它的一些方法来设置是否允许BeanDefinition定义覆盖、是否允许循环引用等,然后在AbstractAutowireCapableBeanFactory
的构造器中,设置了几个Aware类的依赖注入检查
/**
* Create a new AbstractAutowireCapableBeanFactory.
*/
public AbstractAutowireCapableBeanFactory() {
super();
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
}
在AbstractAutowireCapableBeanFactory
中设置了父BeanFactory(如果有的话)
/**
* Create a new AbstractAutowireCapableBeanFactory with the given parent.
* @param parentBeanFactory parent bean factory, or {@code null} if none
*/
public AbstractAutowireCapableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
this();
setParentBeanFactory(parentBeanFactory);
}
还记得我们创建的BeanFactory是new的那个子类吗?对,是``,我们也可以通过类图来大概看一下它具备那些能力和属性
解释一个几个Registry(注册器)
- AliasRegistry 要求子类实现提供别名的管理能力(注册、查询等接口)
- BeanDefinitionRegistry 要求子类实现提供BeanDefinitition的管理能力
- SingletonBeanRegistry 要求子类实现提供单例Bean的管理能力
所有new出来的这个DefaultListableBeanFactory就必定有这些相关的接口
对BeanFactory的个性化设置
/**
* Customize the internal bean factory used by this context.
* Called for each {@link #refresh()} attempt.
* <p>The default implementation applies this context's
* {@linkplain #setAllowBeanDefinitionOverriding "allowBeanDefinitionOverriding"}
* and {@linkplain #setAllowCircularReferences "allowCircularReferences"} settings,
* if specified. Can be overridden in subclasses to customize any of
* {@link DefaultListableBeanFactory}'s settings.
* @param beanFactory the newly created bean factory for this context
* @see DefaultListableBeanFactory#setAllowBeanDefinitionOverriding
* @see DefaultListableBeanFactory#setAllowCircularReferences
* @see DefaultListableBeanFactory#setAllowRawInjectionDespiteWrapping
* @see DefaultListableBeanFactory#setAllowEagerClassLoading
*/
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
上面已经提到过了,我们列举几个典型的可被覆盖的BeanFactory属性
- setAllowBeanDefinitionOverriding 是否允许BeanDefinition覆盖,有多个配置来源时可能会产生命名冲突等,这个设置也对Bean的别名覆盖生效。为false时,如果有冲突会抛异常
- setAllowCircularReferences 是否允许Bean之间的循环引用,为true时(默认)会自动解决循环依赖
- setAllowRawInjectionDespiteWrapping 是否允许原始Bean(没有切面和装饰)的注入,默认FALSE,不那么常用,也不鼓励使用
- setAllowEagerClassLoading 是否允许Bean的Class提前加载,及时被标识为lazy-init,默认true
加载BeanDefinition
自此,我们就已经得到了一个BeanFactory对象,这之后,我们将使用BeanFactory实例完成一系列的后续工作。在refreshBeanFactory
中,则有非常重要的一步——loadBeanDefinitions(beanFactory)
,这里面的源码真的是很庞大,我们还是挑重点进行讲解。
BeanDefinition的加载流程请看下个章节:
Spring源码私家笔记——BeanDefinition加载流程