本文要看啥


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

try {
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException var5) {
this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
}

this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}

}

前面的笔记中,我们已经走完了这个方法中的第一步,感觉第一步就走了很远,眼瞅要迷路了,但无论如何,总归是拿到了我们的bdHolder, 里面已经存放了Bean标签里面的默认的元素.

如果bdHolder不为空的话,我们可以继续往下走啦.

今天来研究下这段代码

1
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

看方法名字就大概知道,这里要做的事情就是 如果有需要的话,装饰我们刚拿到的bdHolder.

那么何为需要呢?下面这样的场景便是了

1
2
3
<bean id="test" class="test.myClass">
<mybean:user username="aaa"/>
</bean>

这里的自定义标签和

1
2
3
<mvc:resources mapping="/img/**" location="img/"/>
<aop:config/>
<tx:advice id="transactionAdvice" transaction-manager="transactionManager"/>

并不同,这里的是在bean内的, 而mvc那种标签是在beans里面,与bean同级的

开始进入方法吧


这次要看的主要方法就是 decorateBeanDefinitionIfRequired

这个方法主要是拆开我们之前的bean,将其各属性和各子节点全部变为node,

然后带着每个node和之前的bd去 decorateIfRequired

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  public BeanDefinitionHolder decorateIfRequired(Node node, BeanDefinitionHolder originalDef, BeanDefinition containingBd) {
String namespaceUri = this.getNamespaceURI(node);
//看看是不是默认命名空间, 如果是的话那就不用管了, 在这方法里,我们只需处理自定义的标签
if (!this.isDefaultNamespace(namespaceUri)) {
//拿到这个命名空间的解析器 handler
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
//如果能找到解析器,我们就可以进入装饰方法啦
if (handler != null) {
return handler.decorate(node, originalDef, new ParserContext(this.readerContext, this, containingBd));
}
//以下都是没找到解析器的
//命名空间不为null,而且还以spring家的网址开头,那就报错表示找不到spring解析器
if (namespaceUri != null && namespaceUri.startsWith("http://www.springframework.org/")) {
this.error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", node);
} else if (this.logger.isDebugEnabled()) {
//如果能打日志的话,打个日志完事
this.logger.debug("No Spring NamespaceHandler found for XML schema namespace [" + namespaceUri + "]");
}
}

return originalDef;
}

具体的用handler解析node会在后面详细学习,这个就先到这吧!

前面几篇文章都长得没法看了…吸取教训 篇幅尽量不要太长了.