通过上述源码分析,我们明白了在Spring配置文件中,对
集合元素的解析方法进行源码分析,了解其实现过程。
7.解析
子元素:
在BeanDefinitionParserDelegate类中的parseListElement方法就是具体实现解析
集合子元素,源码如下:
- //解析
-
集合子元素 public List parseListElement(Element collectionEle, BeanDefinition bd) {
- //获取
-
元素中的value-type属性,即获取集合元素的数据类型 String defaultElementType = collectionEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
- //获取
-
集合元素中的所有子节点 NodeList nl = collectionEle.getChildNodes();
- //Spring中将List封装为ManagedList ManagedList
- target.setSource(extractSource(collectionEle)); //设置集合目标数据类型
- target.setElementTypeName(defaultElementType); target.setMergeEnabled(parseMergeAttribute(collectionEle));
- //具体的
-
元素解析 parseCollectionElements(nl, target, bd, defaultElementType);
- return target; }
- //具体解析
-
集合元素,
、 -
和
都使用该方法解析 protected void parseCollectionElements( - NodeList elementNodes, Collection
target, BeanDefinition bd, String defaultElementType) { //遍历集合所有节点 - for (int i = 0; i < elementNodes.getLength(); i++) { Node node = elementNodes.item(i);
- //节点不是description节点 if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT)) {
- //将解析的元素加入集合中,递归调用下一个子元素 target.add(parsePropertySubElement((Element) node, bd, defaultElementType));
- } }
- }
经过对Spring Bean定义资源文件转换的Document对象中的元素层层解析,Spring IoC现在已经将XML形式定义的Bean定义资源文件转换为Spring IoC所识别的数据结构——BeanDefinition,它是Bean定义资源文件中配置的POJO对象在Spring IoC容器中的映射,我们可以通过AbstractBeanDefinition为入口,荣IoC容器进行索引、查询和操作。
通过Spring IoC容器对Bean定义资源的解析后,IoC容器大致完成了管理Bean对象的准备工作,即初始化过程,但是最为重要的依赖注入还没有发生,现在在IoC容器中BeanDefinition存储的只是一些静态信息,接下来需要向容器注册Bean定义信息才能全部完成IoC容器的初始化过程。
8.解析过后的BeanDefinition在IoC容器中的注册:
让我们继续跟踪程序的执行顺序,接下来会到我们第3步中分析DefaultBeanDefinitionDocumentReader对Bean定义转换的Document对象解析的流程中,在其parseDefaultElement方法中完成对Document对象的解析后得到封装BeanDefinition的BeanDefinitionHold对象,然后调用BeanDefinitionReaderUtils的registerBeanDefinition方法向IoC容器注册解析的Bean,BeanDefinitionReaderUtils的注册的源码如下:
[java]- //将解析的BeanDefinitionHold注册到容器中 public static void registerBeanDefinition(
- BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
- //获取解析的BeanDefinition的名称 String beanName = definitionHolder.getBeanName();
- //向IoC容器注册BeanDefinition registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
- //如果解析的BeanDefinition有别名,向容器为其注册别名 String[] aliases = definitionHolder.getAliases();
- if (aliases != null) { for (String aliase : aliases) {
- registry.registerAlias(beanName, aliase); }
- } }
当调用BeanDefinitionReaderUtils向IoC容器注册解析的BeanDefinition时,真正完成注册功能的是DefaultListableBeanFactory。
9.DefaultListableBeanFactory向IoC容器注册解析后的BeanDefinition:
DefaultListableBeanFactory中使用一个HashMap的集合对象存放IoC容器中注册解析的BeanDefinition,向IoC容器注册的主要源码如下:
[java]- //存储注册的俄BeanDefinition private final Map
beanDefinitionMap = new ConcurrentHashMap (); - //向IoC容器注册解析的BeanDefiniton public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
- throws BeanDefinitionSt
- //存储注册的俄BeanDefinition private final Map