默认标签的解析
1 | //DefaultBeanDefinitionDocumentReader |
2 | private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { |
3 | if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { |
4 | //import 标签解析 |
5 | importBeanDefinitionResource(ele); |
6 | } |
7 | else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { |
8 | // alias 标签解析 |
9 | processAliasRegistration(ele); |
10 | } |
11 | else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { |
12 | //bean 标签解析 |
13 | processBeanDefinition(ele, delegate); |
14 | } |
15 | else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { |
16 | // recurse |
17 | // beans 标签的解析 |
18 | doRegisterBeanDefinitions(ele); |
19 | } |
20 | } |
bean 标签的解析及注册
- import , alias,bean, beans 标签中,bean标签的解析最为复杂,现在分析bean标签的解析。
1//DefaultBeanDefinitionDocumentReader2protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {3//bdholder 实例中包含了我们配置文件的各种属性了:class ,name, alias4BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);5if (bdHolder != null) {6// 若默认标签的子节点下再有自定义属性,还需要对自定义属性进行解析7bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);8try {9//BeanDefinitionHolder 中包含了beanName,和BeanDefinintion10//注册beanDefintion 到BeanDefinitionRegistry中,key: beanname,value:BeanDefinition11// Register the final decorated instance.12BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());13}14catch (BeanDefinitionStoreException ex) {15getReaderContext().error("Failed to register bean definition with name '" +16bdHolder.getBeanName() + "'", ele, ex);17}18//通知简体器bean已经加载完毕。19// Send registration event.20getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));21}22}
解析BeanDefinition
- BeanDefinitionHolder 获取:
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);1//BeanDefinitionParserDelegate23public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {4//解析id属性5String id = ele.getAttribute(ID_ATTRIBUTE);6// 解析name属性7String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);8//别名,多个用 "," 分割9List<String> aliases = new ArrayList<>();10if (StringUtils.hasLength(nameAttr)) {11String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);12aliases.addAll(Arrays.asList(nameArr));13}14// 设置beanName,如果id为空,如果BeanName则取aliases的第一个值15String beanName = id;16if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {17beanName = aliases.remove(0);18if (logger.isDebugEnabled()) {19logger.debug("No XML 'id' specified - using '" + beanName +20"' as bean name and " + aliases + " as aliases");21}22}23if (containingBean == null) {24checkNameUniqueness(beanName, aliases, ele);25}26// 0127AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);28if (beanDefinition != null) {29if (!StringUtils.hasText(beanName)) {30try {31if (containingBean != null) {32beanName = BeanDefinitionReaderUtils.generateBeanName(33beanDefinition, this.readerContext.getRegistry(), true);34}35else {36beanName = this.readerContext.generateBeanName(beanDefinition);37// 如果不存在beanName 那么根据Spring 提供的命名规则为当前的bean生成对应的beanName38// Register an alias for the plain bean class name, if still possible,39// if the generator returned the class name plus a suffix.40// This is expected for Spring 1.2/2.0 backwards compatibility.41String beanClassName = beanDefinition.getBeanClassName();42if (beanClassName != null &&43beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&44!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {45aliases.add(beanClassName);46}47}48if (logger.isDebugEnabled()) {49logger.debug("Neither XML 'id' nor 'name' specified - " +50"using generated bean name [" + beanName + "]");51}52}53catch (Exception ex) {54error(ex.getMessage(), ele);55return null;56}57}58String[] aliasesArray = StringUtils.toStringArray(aliases);59return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);60}61return null;62}
AbstractBeanDefinition 包含每个bean中都有的基础信息
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);1////BeanDefinitionParserDelegate23public AbstractBeanDefinition parseBeanDefinitionElement(4Element ele, String beanName, @Nullable BeanDefinition containingBean) {5this.parseState.push(new BeanEntry(beanName));6//解析class属性7String className = null;8if (ele.hasAttribute(CLASS_ATTRIBUTE)) {9className = ele.getAttribute(CLASS_ATTRIBUTE).trim();10}11// 解析partent 属性12String parent = null;13if (ele.hasAttribute(PARENT_ATTRIBUTE)) {14parent = ele.getAttribute(PARENT_ATTRIBUTE);15}16try {17// 创建承载属性的GenericBeanDefinition(父类为AbstractBeanDefinition)18AbstractBeanDefinition bd = createBeanDefinition(className, parent);19//硬编码解析bean的各种属性20parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);21//提取描述信息22bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));23// 解析 mata 元数据24parseMetaElements(ele, bd);25//解析Lookup—method 属性26parseLookupOverrideSubElements(ele, bd.getMethodOverrides());27//解析replaced-method 属性28parseReplacedMethodSubElements(ele, bd.getMethodOverrides());29// 解析 constructor-arg 属性30parseConstructorArgElements(ele, bd);31// 解析property 属性32parsePropertyElements(ele, bd);33//解析 qualifier 属性34parseQualifierElements(ele, bd);35bd.setResource(this.readerContext.getResource());36bd.setSource(extractSource(ele));37return bd;38}39catch (ClassNotFoundException ex) {40error("Bean class [" + className + "] not found", ele, ex);41}42finally {43this.parseState.pop();44}45return null;46}BeanDefinition (interface)继承关系

各种标签
- mata标签
- lookup-method
- replaced-method
- constructor-arg
- property
- qualifier
AbstractBeanDefinition
- 定义了一些标签的配置信息和取值范围。
注册BeanDefinition
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());1//BeanDefinitionReaderUtils2public static void registerBeanDefinition(3BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)4throws BeanDefinitionStoreException {5// Register bean definition under primary name.6String beanName = definitionHolder.getBeanName();7registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());89// Register aliases for bean name, if any.10String[] aliases = definitionHolder.getAliases();11if (aliases != null) {12for (String alias : aliases) {13registry.registerAlias(beanName, alias);14}15}16}
通知监听器解析及注册完成
1 | //通知简体器bean已经加载完毕。 |
2 | // Send registration event. |
3 | getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); |
该方法为空,项目中如果对bean 的加载需要监控,则需要拓展该方法,spring 自身没有对该方法做任何处理。