基於XmlBeanFactory加載bean分析:parseDefaultElement(二)

本節主要針對bean標籤的解析源碼分析java

DefaultBeanDefinitionDocumentReader.java 完成了對element的解析node

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
	if(delegate.nodeNameEquals(ele, "import")) {//導入
		this.importBeanDefinitionResource(ele);
	} else if(delegate.nodeNameEquals(ele, "alias")) {//別名
		this.processAliasRegistration(ele);
	} else if(delegate.nodeNameEquals(ele, "bean")) {//bean
		this.processBeanDefinition(ele, delegate);
	} else if(delegate.nodeNameEquals(ele, "beans")) {//bean集合
		this.doRegisterBeanDefinitions(ele);
	}

}
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
	//經過BeanDefinition解析器去解析ele,而後返回BeanDefinitionHolder(也就是返回具體的BeanDefinition,beanName,ailas)
	BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);//【分支01】
	if(bdHolder != null) {
		//bdHolder實例不爲空,須要對標籤下的自定義標籤,再次解析//【分支02】
		bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

		try {
			//當拿到BeanDefinitionHolder後,須要將解析的bean註冊到Spring容器中//【分支03】
			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));
	}

}

【分支01】主要分析了若是把element解析爲一個BeanDefinitionHolder對象session

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
    return this.parseBeanDefinitionElement(ele, (BeanDefinition)null);
}
//具體的bean解析(當前分析時containingBean爲空)
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
	String id = ele.getAttribute("id");//在element節點中獲取id屬性
	String nameAttr = ele.getAttribute("name");//在element節點獲取name屬性
	//---處理alias開始
	ArrayList aliases = new ArrayList();//將全部的name都當成別名先記錄起來
	if(StringUtils.hasLength(nameAttr)) {
		String[] beanName = StringUtils.tokenizeToStringArray(nameAttr, ",; ");
		aliases.addAll(Arrays.asList(beanName));
	}
	//---處理alias結束
	String beanName1 = id;
	//這裏若是發現未設置id屬性時,直接從name屬性中獲取,而後移除一個name屬性
	if(!StringUtils.hasText(id) && !aliases.isEmpty()) {
		beanName1 = (String)aliases.remove(0);
	}
	//驗證name以及別名信息是否惟一【分支0101】
	if(containingBean == null) {
		this.checkNameUniqueness(beanName1, aliases, ele);
	}
	//建立一個beanDefinition對象【分支0102】
	AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName1, containingBean);
	if(beanDefinition != null) {
		if(!StringUtils.hasText(beanName1)) {
			try {
				if(containingBean != null) {
					beanName1 = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);
				} else {
					beanName1 = this.readerContext.generateBeanName(beanDefinition);
					String aliasesArray = beanDefinition.getBeanClassName();
					if(aliasesArray != null && beanName1.startsWith(aliasesArray) && beanName1.length() > aliasesArray.length() && !this.readerContext.getRegistry().isBeanNameInUse(aliasesArray)) {
						aliases.add(aliasesArray);
					}
				}

				if(this.logger.isDebugEnabled()) {
					this.logger.debug("Neither XML \'id\' nor \'name\' specified - using generated bean name [" + beanName1 + "]");
				}
			} catch (Exception var9) {
				this.error(var9.getMessage(), ele);
				return null;
			}
		}

		String[] aliasesArray1 = StringUtils.toStringArray(aliases);
		return new BeanDefinitionHolder(beanDefinition, beanName1, aliasesArray1);
	} else {
		return null;
	}
}

【分支0101】驗證name以及別名信息是否惟一ide

BeanDefinitionParserDelegate.java中函數

--【分支0101】驗證name以及別名信息是否惟一
private final Set<String> usedNames = new HashSet();
protected void checkNameUniqueness(String beanName, List<String> aliases, Element beanElement) {
	String foundName = null;
	//查詢usedNames是否包含當前beanName
	if(StringUtils.hasText(beanName) && this.usedNames.contains(beanName)) {
		foundName = beanName;
	}

	//判斷當前別名與已註冊的usedNames信息是否相同
	if(foundName == null) {
		foundName = (String)CollectionUtils.findFirstMatch(this.usedNames, aliases);
	}

	if(foundName != null) {
		this.error("Bean name \'" + foundName + "\' is already used in this <beans> element", beanElement);
	}
	//usedNames存放了beanName和alias信息
	this.usedNames.add(beanName);
	this.usedNames.addAll(aliases);
}

這裏主要使用了源碼分析

Set集合存儲usedNames,其中usedNames包含beanName以及aliases信息。ui

【分支0102】建立一個beanDefinition對象(其原型類爲AbstractBeanDefinition)this

BeanDefinitionParserDelegate.java中prototype

AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName1, containingBean);
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean) {
	this.parseState.push(new BeanEntry(beanName));
	String className = null;
	//獲取當前節點的class屬性
	if(ele.hasAttribute("class")) {
		className = ele.getAttribute("class").trim();
	}

	try {
		String ex = null;
		//判斷並獲取當前節點的parent屬性
		if(ele.hasAttribute("parent")) {
			ex = ele.getAttribute("parent");
		}
		//下面描述了AbstractBeanDefinition如何建立而且講解了AbstractBeanDefinition相關類圖結構以瞭解具體裏面幹了些什麼事
		AbstractBeanDefinition bd = this.createBeanDefinition(className, ex);
		//當拿到bean屬性BeanDefinition以後,經過當前element節點信息,基礎設置AbstractBeanDefinition的屬性
		this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
		//設置description描述信息
		bd.setDescription(DomUtils.getChildElementValueByTagName(ele, "description"));
		//處理meta標籤(實際開發中好像還沒使用到過)
		this.parseMetaElements(ele, bd);
		//處理lookup-method標籤
		this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
		//處理replaced-method標籤
		this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
		//處理構造函數constructor-arg標籤
		this.parseConstructorArgElements(ele, bd);
		//處理property標籤
		this.parsePropertyElements(ele, bd);
		//處理qualifier標籤
		this.parseQualifierElements(ele, bd);
		//設置resource屬性
		bd.setResource(this.readerContext.getResource());
		//設置source屬性
		bd.setSource(this.extractSource(ele));
		AbstractBeanDefinition var7 = bd;
		return var7;
	} catch (ClassNotFoundException var13) {
		this.error("Bean class [" + className + "] not found", ele, var13);
	} catch (NoClassDefFoundError var14) {
		this.error("Class that bean class [" + className + "] depends on not found", ele, var14);
	} catch (Throwable var15) {
		this.error("Unexpected failure during bean definition parsing", ele, var15);
	} finally {
		this.parseState.pop();
	}

	return null;
}

咱們看到上面處理了不少標籤,這些標籤都是咱們平常在xml配置的屬性節點。也就是這裏主要完成xml配置中對屬性節點的解析。debug

this.createBeanDefinition(className, ex)建立一個AbstractBeanDefinition

protected AbstractBeanDefinition createBeanDefinition(String className, String parentName) throws ClassNotFoundException {
	return BeanDefinitionReaderUtils.createBeanDefinition(parentName, className, this.readerContext.getBeanClassLoader());
}

BeanDefinitionReaderUtils.createBeanDefinition方法

public static AbstractBeanDefinition createBeanDefinition(String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException {
	//GenericBeanDefinition爲AbstractBeanDefinition的實現類;這裏主要完成GenericBeanDefinition的初始化工做,調用了AbstractBeanDefinition無參的構造函數完成基本信息的初始化等
	GenericBeanDefinition bd = new GenericBeanDefinition();
	bd.setParentName(parentName);
	if(className != null) {
		if(classLoader != null) {
			bd.setBeanClass(ClassUtils.forName(className, classLoader));
		} else {
			bd.setBeanClassName(className);
		}
	}

	return bd;
}

而後咱們回到【分支0102】分支中的

//當拿到bean屬性BeanDefinition以後,經過當前element節點信息,基礎設置AbstractBeanDefinition的屬性
this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);

//設置AbstractBeanDefinition屬性的值
//這裏面主要完成了對element節點信息的獲取和解析並將解析的參數設置到AbstractBeanDefinition中,完成AbstractBeanDefinition的進一步初始化
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, BeanDefinition containingBean, AbstractBeanDefinition bd) {
	//這裏明確說明,在1.x之後singleton標籤已經被scope做用域標籤代替【scope可選值:singleton,prototype,request,session】
	if(ele.hasAttribute("singleton")) {
		this.error("Old 1.x \'singleton\' attribute in use - upgrade to \'scope\' declaration", ele);
	} else if(ele.hasAttribute("scope")) {//若是包含scope則設置AbstractBeanDefinition中的scope屬性
		bd.setScope(ele.getAttribute("scope"));
	} else if(containingBean != null) {//這裏明確若是包含containingBean那麼做用域確定在containingBean中。可是根據規則以socpe爲主
		bd.setScope(containingBean.getScope());
	}
	
	//設置AbstractBeanDefinition的abstract 是否爲抽象類的標識
	if(ele.hasAttribute("abstract")) {
		bd.setAbstract("true".equals(ele.getAttribute("abstract")));
	}
	//設置延遲初始
	String lazyInit = ele.getAttribute("lazy-init");
	if("default".equals(lazyInit)) {
		lazyInit = this.defaults.getLazyInit();
	}

	bd.setLazyInit("true".equals(lazyInit));
	String autowire = ele.getAttribute("autowire");
	//這裏在當前getAutowireMode方法中去查找自動注入方式;
	//咱們看到當前類存在這樣一個屬性private final DocumentDefaultsDefinition defaults = new DocumentDefaultsDefinition();在populateDefaults方法完成document文檔根節點類的加載。例如在根節點上面設置default-autowire="byType"等設置
	bd.setAutowireMode(this.getAutowireMode(autowire));
	String dependencyCheck = ele.getAttribute("dependency-check");
	bd.setDependencyCheck(this.getDependencyCheck(dependencyCheck));
	String autowireCandidate;
	if(ele.hasAttribute("depends-on")) {
		autowireCandidate = ele.getAttribute("depends-on");
		bd.setDependsOn(StringUtils.tokenizeToStringArray(autowireCandidate, ",; "));
	}

	autowireCandidate = ele.getAttribute("autowire-candidate");
	String destroyMethodName;
	if(!"".equals(autowireCandidate) && !"default".equals(autowireCandidate)) {
		bd.setAutowireCandidate("true".equals(autowireCandidate));
	} else {
		destroyMethodName = this.defaults.getAutowireCandidates();
		if(destroyMethodName != null) {
			String[] patterns = StringUtils.commaDelimitedListToStringArray(destroyMethodName);
			bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
		}
	}

	if(ele.hasAttribute("primary")) {
		bd.setPrimary("true".equals(ele.getAttribute("primary")));
	}

	if(ele.hasAttribute("init-method")) {
		destroyMethodName = ele.getAttribute("init-method");
		if(!"".equals(destroyMethodName)) {
			bd.setInitMethodName(destroyMethodName);
		}
	} else if(this.defaults.getInitMethod() != null) {
		bd.setInitMethodName(this.defaults.getInitMethod());
		bd.setEnforceInitMethod(false);
	}

	if(ele.hasAttribute("destroy-method")) {
		destroyMethodName = ele.getAttribute("destroy-method");
		bd.setDestroyMethodName(destroyMethodName);
	} else if(this.defaults.getDestroyMethod() != null) {
		bd.setDestroyMethodName(this.defaults.getDestroyMethod());
		bd.setEnforceDestroyMethod(false);
	}

	if(ele.hasAttribute("factory-method")) {
		bd.setFactoryMethodName(ele.getAttribute("factory-method"));
	}

	if(ele.hasAttribute("factory-bean")) {
		bd.setFactoryBeanName(ele.getAttribute("factory-bean"));
	}

	return bd;
}

對其餘標籤的分析能夠單獨列出來分析,這裏就不具體分析了。

切入【分支03】當拿到BeanDefinitionHolder後,須要將解析的bean註冊到Spring容器中

BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry())

public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
	//獲取當前註冊的beanName
	String beanName = definitionHolder.getBeanName();
	//registry爲xmlBeanFactory,他就是一個bean工廠類主要就是完成bean的註冊
	registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
	String[] aliases = definitionHolder.getAliases();
	if(aliases != null) {
		String[] var4 = aliases;
		int var5 = aliases.length;

		for(int var6 = 0; var6 < var5; ++var6) {
			String alias = var4[var6];
			registry.registerAlias(beanName, alias);
		}
	}

}

//在實現類DefaultListableBeanFactory完成了registerBeanDefinition註冊bean

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
	Assert.hasText(beanName, "Bean name must not be empty");
	Assert.notNull(beanDefinition, "BeanDefinition must not be null");
	if(beanDefinition instanceof AbstractBeanDefinition) {
		try {
			((AbstractBeanDefinition)beanDefinition).validate();
		} catch (BeanDefinitionValidationException var9) {
			throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var9);
		}
	}

	BeanDefinition oldBeanDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
	if(oldBeanDefinition != null) {
		if(!this.isAllowBeanDefinitionOverriding()) {
			throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean \'" + beanName + "\': There is already [" + oldBeanDefinition + "] bound.");
		}

		if(oldBeanDefinition.getRole() < beanDefinition.getRole()) {
			if(this.logger.isWarnEnabled()) {
				this.logger.warn("Overriding user-defined bean definition for bean \'" + beanName + "\' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
			}
		} else if(!beanDefinition.equals(oldBeanDefinition)) {
			if(this.logger.isInfoEnabled()) {
				this.logger.info("Overriding bean definition for bean \'" + beanName + "\' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
			}
		} else if(this.logger.isDebugEnabled()) {
			this.logger.debug("Overriding bean definition for bean \'" + beanName + "\' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
		}

		this.beanDefinitionMap.put(beanName, beanDefinition);
	} else {
		if(this.hasBeanCreationStarted()) {
			Map var4 = this.beanDefinitionMap;
			synchronized(this.beanDefinitionMap) {
				this.beanDefinitionMap.put(beanName, beanDefinition);
				ArrayList updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
				updatedDefinitions.addAll(this.beanDefinitionNames);
				updatedDefinitions.add(beanName);
				this.beanDefinitionNames = updatedDefinitions;
				if(this.manualSingletonNames.contains(beanName)) {
					LinkedHashSet updatedSingletons = new LinkedHashSet(this.manualSingletonNames);
					updatedSingletons.remove(beanName);
					this.manualSingletonNames = updatedSingletons;
				}
			}
		} else {
			this.beanDefinitionMap.put(beanName, beanDefinition);
			this.beanDefinitionNames.add(beanName);
			this.manualSingletonNames.remove(beanName);
		}

		this.frozenBeanDefinitionNames = null;
	}

	if(oldBeanDefinition != null || this.containsSingleton(beanName)) {
		this.resetBeanDefinition(beanName);
	}

}
相關文章
相關標籤/搜索