03-Spring 初始化过程中PreInstantiateSingletons方法分析

2,274 阅读1分钟

在完成前两篇文章的操作后,会通过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的细节。