关键步骤
   
    BeanFactory注册涉及到几个关键的的步骤
    
    1、Resource定位:就是找到定义JavaBean信息的xml文件,并将其封装为Resource对象
    
    2、BeanDedefinition载入:把用户定义好的Javabean表示为Ioc容器内部的数据结构
    
    3、注册BeanDefinition到ioc容器
   
    
    
    过程分析
   
    分析BeanFactory的创建流程不是简单的去看如何new一个BeanFactory对象,而是看BeanDefinition如何加载到BeanFactory这一过程。
    
    我们通过上一篇文章《Ioc源码分析-ioc容器初始化主流程》可以知道BeanDefinition的注册到BeanFactory是在obtainFreshBeanFactory这个方法中,接下来我们就点进这个方法看一下,他是如何注册的
    
    
    
    我们点进这个方法以后就可以看到一个名叫refreshBeanFactory的方法,然后我们看一下这个方法
   
	protected final void refreshBeanFactory() throws BeansException {
		// 判断是否已经存在beanFactory
		if (hasBeanFactory()) {
			// 销毁beans
			destroyBeans();
			// 关闭工厂
			closeBeanFactory();
		}
		try {
			// 实例化DefaultListableBeanFactory
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			// 设置序列化id
			beanFactory.setSerializationId(getId());
			// 为beanFactory填充属性
			customizeBeanFactory(beanFactory);
			// 加载BeanDefinition
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}
    那么通过上面的方法我们,我们可以看到有一个LodaBeanDefinition方法,加载BeanDefinition,这个应该就是我们要看的方法入口,接着点进去
    
    熟悉源码的同学都知道,在spring源码中,通常实际的执行实现方法通常方法名都会有doXXXX,createXXX等动词开头,所以我们经过依次调用多个类的 loadBeanDefinitions 方法 —> AbstractXmlApplicationContext —>
    
    AbstractBeanDefinitionReader —> XmlBeanDefinitionReader ⼀直执行到
    
    XmlBeanDefinitionReader 的 doLoadBeanDefinitions 方法
   
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {
		try {
			// 解析xml文件,获取document对象
			Document doc = doLoadDocument(inputSource, resource);
			// 注册BeanDefinition
			int count = registerBeanDefinitions(doc, resource);
			if (logger.isDebugEnabled()) {
				logger.debug("Loaded " + count + " bean definitions from " + resource);
			}
			return count;
		}
		}
同样经过一些重载方法,我们定位到registerBeanDefinition方法
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		// 获取已有BeanDefinition的个数
		int countBefore = getRegistry().getBeanDefinitionCount();
		// 注册BeanDefinition
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}
    这个方法中我们重点关注两个方法,一个是createReaderContexet方法,一个是registerBeanDefinition方法
    
    先看createReaderContext
    
    
    
    我们可以看到这个方法初始化了nameSpaceHandler
    
    然后我们再返回去看registerBeanDefinition方法
   
	@Override
	public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
		this.readerContext = readerContext;
		doRegisterBeanDefinitions(doc.getDocumentElement());
	}
找到doRegisterBeanDefinition方法
	protected void doRegisterBeanDefinitions(Element root) {
		............
		preProcessXml(root);
		parseBeanDefinitions(root, this.delegate);
		postProcessXml(root);
		this.delegate = parent;
	}
这个方法里面我们重点关注parseBeanDefinition方法,perProcessXml前置处理,和PostProcessxml后置处理先不看
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
		if (delegate.isDefaultNamespace(root)) {
			NodeList nl = root.getChildNodes();
			for (int i = 0; i < nl.getLength(); i++) {
				Node node = nl.item(i);
				if (node instanceof Element) {
					Element ele = (Element) node;
					if (delegate.isDefaultNamespace(ele)) {
					    // 解析元素标签
						parseDefaultElement(ele, delegate);
					}
					else {
						// 解析自定义元素标签
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else {
			// 解析自定义元素标签
			delegate.parseCustomElement(root);
		}
	}
进入parseDefaultElement
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
		// import元素
		if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
			importBeanDefinitionResource(ele);
		}
		// alias元素
		else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
			processAliasRegistration(ele);
		}
		// bean元素
		else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
			processBeanDefinition(ele, delegate);
		}
		// nested元素
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
			// recurse
			doRegisterBeanDefinitions(ele);
		}
	}
我们看processBeanDefinition方法解析bean标签
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
	           .............
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			................
	}
我们最后看registerBeanDefinition方法
	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {
    ...................
        // 判断Bean是否已经存在
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
			...........
		}
		else {
			// 判断该bean有没有正在被注册
			if (hasBeanCreationStarted()) {
				...............
			}
			// 注册到BeanFactory中
			else {
				// Still in startup registration phase
				// 存放
				this.beanDefinitionMap.put(beanName, beanDefinition);
				this.beanDefinitionNames.add(beanName);
				removeManualSingletonName(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}
		if (existingDefinition != null || containsSingleton(beanName)) {
			resetBeanDefinition(beanName);
		}
	}
那我们可以看出BeanDefinition注册到BeanFactory中,其实就是把BeanDefinition存放到一个map中
	/** Map of bean definition objects, keyed by bean name. */
	private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
    
    
    时序图
   
     
   
 
