一、AnnotationConfigApplicationContext和DefaultListableBeanFactory的关系
AnnotationConfigApplicationContext的父类GenericApplicationContext包含了DefaultListableBeanFactory,如下图:
后续ApplicationContext涉及到对Bean工厂的操作,其实操作的都是DefaultListableBeanFactory这个Bean工厂实现类。
二、DefaultListableBeanFactory和BeanDefinitionRegistry的关系
先看下类的关系图:
由图可知,DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,而BeanDefinitionRegistry仅仅只提供BeanDefinition的注册表功能,无工厂功能(可以理解成获取Bean实例的功能)。
三、DefaultListableBeanFactory中的beanDefinitionMap和beanDefinitionNames的意义
1、beanDefinitionMap很好理解就是存放BeanDefinition的Map集合,从源码注释就可以清晰的看到他的含义:/**
Map of bean definition objects, keyed by bean name */。
2、beanDefinitionNames是存放beanDefinitionName的List集合,源码注释为:/** List of
bean definition names, in registration order
*/,结合数据结构的知识可以联想到,List集合具有有序性,也就是说beanDefinitionNames是有序的,那在哪有序添加的呢?又为何要有序存放呢?
a) 有序添加的地方是在注册BeanDefinition的时候,请看下篇文章。
b) 为何有序存放,因为在Spring创建单例bean的时候,就是迭代beanDefinitionNames来有序实例化bean的,源码调用栈如下:
AbstractApplicationContext#refresh
->AbstractApplicationContext#finishBeanFactoryInitialization
->DefaultListableBeanFactory#preInstantiateSingletons
DefaultListableBeanFactory#preInstantiateSingletons方法的核心代码如下:
public void preInstantiateSingletons() throws BeansException {
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
}