在完成前两篇文章的操作后,会通过finishBeanFactoryInitialization方法创建已经注册的beanDefinitionMap中的类。此处只分析实际起作用的PreInstantiateSingletons方法。 Spring在实例化的时候会进行判断,只有单例,并且不是LazyInit的Bean才会在初始化过程中创建,其他的比如Prototype或Lazy的只有在使用到时会通过getBean来创建。下面我们来分析实例化Bean的过程
@Override
public void preInstantiateSingletons() throws BeansException {
// 先得到BeanDefinitionMap中已经注册的所有Bean Definition名称
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 依次遍历所有的名称
for (String beanName : beanNames) {
// 获取bd(Bean Definition),判断当前bd所代表的类不是Abstract的,也不是需要延迟加载的并且是单例的。
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 判断当前bd代表的累是否为工厂,此方法内部会调用依次getObject方法,由于Spring自己的类(BeanPostProcessor)在前面注册时已经实例化,故可以直接获取到。而自定义的Bean在并不会生成对象,会通过bd来判断是否为工厂Bean,此处先不讨论FactoryBean的情况,先来分析普通Bean
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
// 这里从ioc容器中获取bean,如果不存在则创建
getBean(beanName);
}
}
}
}
通过上面的铺垫,getBean才是真正的重头戏,本篇篇幅较短,但我们熟悉了在获取Bean前的基本操作,下一篇我们会展开讨论getBean的细节。