一、Bean的解析(以XmlBeanFactory为例来说明)
1、构造级联容器
AbstractBeanFactory.java
public void setParentBeanFactory(BeanFactory parentBeanFactory) {
// 如果当前容器已经指定了父容器,且新的父容器与当前的父容器不相同,则出错了;
if (this.parentBeanFactory != null && this.parentBeanFactory != parentBeanFactory) {
throw new IllegalStateException("Already associated with parent BeanFactory: " + this.parentBeanFactory);
}
this.parentBeanFactory = parentBeanFactory;
}
2、生成XmlBeanDefinitionReader
XmlBeanFactory.java
// new一个XmlBeanDefinitionReader,在解析bean配置文件时,直接将bean定义信息放到BeanDefinitionRegistry里
// 这里把当前容器作为参数传入,是因为XmlBeanFactory实现了BeanDefinitionRegistry接口
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
3、利用上面构造的reader解析XML文件,装载bean
this.reader.loadBeanDefinitions(resource);
解析
XmlBeanDefinitionReader.java
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isInfoEnabled()) {
logger.info("Loading XML bean definitions from " + encodedResource.getResource());
}
Set currentResources = (Set) this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
// 这里使用ThreadLocal防止循环装载bean
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected recursive loading of " + encodedResource + " - check your import definitions!");
}
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
// 从这里开始解析并装载bean
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
finally {
inputStream.close();
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
// 装载完后,移除该bean定义文件
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.set(null);
}
}
}
XmlBeanDefinitionReader.java
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
int validationMode = getValidationModeForResource(resource);
Document doc = this.documentLoader.loadDocument(
inputSource, getEntityResolver(), this.errorHandler, validationMode, isNamespaceAware());
// 对XML进行校验后,注册bean信息
return registerBeanDefinitions(doc, resource);
}
...
}
XmlBeanDefinitionReader.java
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
...
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
// 交由DefaultBeanDefinitionDocumentReader完成读取bean的工作
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
// 返回当前resource注册到容器中的bean的数量
return getRegistry().getBeanDefinitionCount() - countBefore;
}
DefaultBeanDefinitionDocumentReader.java
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
BeanDefinitionParserDelegate delegate = createHelper(readerContext, root);
preProcessXml(root);
// 由代理类BeanDefinitionParserDelegate完成解析
parseBeanDefinitions(root, delegate);
postProcessXml(root);
}
DefaultBeanDefinitionDocumentReader.java
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root.getNamespaceURI())) {
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;
String namespaceUri = ele.getNamespaceURI();
if (delegate.isDefaultNamespace(namespaceUri)) {
// 解析每个element
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
DefaultBeanDefinitionDocumentReader.java
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
// 如果元素名是import
if (DomUtils.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
// 如果元素名是alias
else if (DomUtils.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
// 如果元素名是bean
else if (DomUtils.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
}
从这里可以看到:
- 如果bean配置文件中使用到了import元素,也是在这里处理的,其处理过程和上面的一致;
- 如果是别名,则直接将别名注册到beanName上;
生成BeanDefinition
DefaultBeanDefinitionDocumentReader.java
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 解析element的亚属性,封装成BeanDefinition,然后和beanName、别名(主属性)一起组装成BeanDefinitionHolder
// 这里把解析bean元素的工作完成委托给BeanDefinitionParseDelegate类来完成
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 注册刚才生成的BeanDefinitionHolder到容器中
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
注册到容器中
BeanDefinitionReaderUtils.java
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// 注册bean信息
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 注册别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (int i = 0; i < aliases.length; i++) {
registry.registerAlias(beanName, aliases[i]);
}
}
}
4、小结
- 其实,这里看着这么多代码,但其作用只有一个,那就是解析XML里的每个元素,获取Spring规范定义的bean的属性值,然后生成BeanDefinition实例;
- 上面提到一点,解析bean的繁锁工作全部由BeanDefinitionParseDelegate类来完成,从这一点也可以看出,Spring中类的职责分工相当的明确;