解析默认Bean标签
Spring默认标签有四个,分别是import、alias、bean、beans,其中关于bean的逻辑最为复杂,所以我们首先从bean标签开始分析,只要掌握了bean标签的逻辑,那么其他标签也不在话下。
![](https://i-blog.csdnimg.cn/blog_migrate/d5d0bfe5989cab0417bb2a9f83fe5d23.png)
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
//解析import标签
if (delegate.nodeNameEquals(ele, "import")) {
this.importBeanDefinitionResource(ele);
//解析alias标签
} else if (delegate.nodeNameEquals(ele, "alias")) {
this.processAliasRegistration(ele);
//解析bean标签
} else if (delegate.nodeNameEquals(ele, "bean")) {
this.processBeanDefinition(ele, delegate);
//解析beans标签
} else if (delegate.nodeNameEquals(ele, "beans")) {
this.doRegisterBeanDefinitions(ele);
}
}
Bean标签解析
processBeanDefinition
![](https://i-blog.csdnimg.cn/blog_migrate/ec2e25280317b8b447602e6bc06ab3e5.png)
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//通过该方法,委托BeanDefinitionParserDelegate解析元素
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
//判断当前的bean是否需要修饰
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
//注册bean
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException var5) {
this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
}
//通知上下文bean注册成功
this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
Spring如何解析和提取配置文件的信息的呢?我们进入方法delegate.parseBeanDefinitionElement(ele):
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
//获取id属性
String id = ele.getAttribute("id");
//获取name属性
String nameAttr = ele.getAttribute("name");
List<String> aliases = new ArrayList();
//将name按照“,;”切割
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; ");
//存入集合中
aliases.addAll(Arrays.asList(nameArr));
}
//将id设为beanName
String beanName = id;
//如果id为空,alises不为空
if (!StringUtils.hasText(id) && !aliases.isEmpty()) {
//将alises的第一个元素作为beanName
beanName = (String)aliases.remove(0);
if (this.logger.isTraceEnabled()) {
this.logger.trace("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases");
}
}
//校验beanName是否唯一
if (containingBean == null) {
this.checkNameUniqueness(beanName, aliases, ele);
}
//解析bean信息元素
AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {
//如果不存在beanName,那么使用Spring的命名规则为当前Bean生成beanName
//bean配置在xml文件中如果设置了class: 那么以class全路径作为beanName
//如果没有设置class:检查是否设置了parent属性,如果设置了parent,则beanName=parentName+"$child";
//否则检查是否设置了factory-bean属性,如果设置了,那么已factory-bean + "$created" 作为beanName检测生成的beanName是否已被注册,如果被注册,那么以一个数字作为后缀区分
beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);
} else {
beanName = this.readerContext.generateBeanName(beanDefinition);
//获取bean的className
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Neither XML 'id' nor 'name' specified - using generated bean name [" + beanName + "]");
}
} catch (Exception var9) {
this.error(var9.getMessage(), ele);
return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
//封装到BeanDefinitionHolder中
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
} else {
return null;
}
}
校验beanName是否唯一:
this.checkNameUniqueness(beanName, aliases, ele)
![](https://i-blog.csdnimg.cn/blog_migrate/ccea6a928558effd1c709604e8ded115.png)
protected void checkNameUniqueness(String beanName, List<String> aliases, Element beanElement) {
String foundName = null;
//如果beanName不为空并且使用的name中包含了beanName
if (StringUtils.hasText(beanName) && this.usedNames.contains(beanName)) {
//给foundName赋值
foundName = beanName;
}
//如果在使用的name中匹配到了别名
if (foundName == null) {
//给foundName赋值
foundName = (String)CollectionUtils.findFirstMatch(this.usedNames, aliases);
}
//当foundName不为空,说明此名字已经被使用过
if (foundName != null) {
this.error("Bean name '" + foundName + "' is already used in this <beans> element", beanElement);
}
//否则就将beanName和alises都存入集合中
this.usedNames.add(beanName);
this.usedNames.addAll(aliases);
}
解析bean的信息元素
this.parseBeanDefinitionElement(ele, beanName, containingBean)
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
String className = null;
//获取class属性
if (ele.hasAttribute("class")) {
className = ele.getAttribute("class").trim();
}
String parent = null;
//获取parent属性
if (ele.hasAttribute("parent")) {
parent = ele.getAttribute("parent");
}
try {
//创建保存属性的载体AbstractBeanDefinition
//其包含了配置文件中的所有属性并且一一对应
AbstractBeanDefinition bd = this.createBeanDefinition(className, parent);
//解析默认bean的属性
this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
//设置说明
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, "description"));
//解析元数据
this.parseMetaElements(ele, bd);
//解析lookUp方法
this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
//解析replace方法
this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
//解析constructor-arg
this.parseConstructorArgElements(ele, bd);
//解析properties属性
this.parsePropertyElements(ele, bd);
//解析qualifier属性
this.parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
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;
}
解析默认bean标签
this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, @Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {
//如果存在singleton属性,直接抛出异常
if (ele.hasAttribute("singleton")) {
this.error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
//获取scope属性
} else if (ele.hasAttribute("scope")) {
bd.setScope(ele.getAttribute("scope"));
} else if (containingBean != null) {
//当存在嵌入beanDefinition且未单独指定scope时,默认使用父类的scope
bd.setScope(containingBean.getScope());
}
//获取abstract属性
if (ele.hasAttribute("abstract")) {
//当abstract设置其他非true的值或者为设置时,均为false
bd.setAbstract("true".equals(ele.getAttribute("abstract")));
}
//获取lazy-init属性
String lazyInit = ele.getAttribute("lazy-init");
if (this.isDefaultValue(lazyInit)) {
lazyInit = this.defaults.getLazyInit();
}
//同上
bd.setLazyInit("true".equals(lazyInit));
//获取autowire属性
String autowire = ele.getAttribute("autowire");
//设置自动注入的方式
//1 ==> byName
//2 ==> byType
//3 ==> constructor
//4 ==> autodetect
bd.setAutowireMode(this.getAutowireMode(autowire));
//解析depends-on属性
String autowireCandidate;
if (ele.hasAttribute("depends-on")) {
autowireCandidate = ele.getAttribute("depends-on");
bd.setDependsOn(StringUtils.tokenizeToStringArray(autowireCandidate, ",; "));
}
//解析autowire-candidate属性
autowireCandidate = ele.getAttribute("autowire-candidate");
String destroyMethodName;
if (this.isDefaultValue(autowireCandidate)) {
destroyMethodName = this.defaults.getAutowireCandidates();
if (destroyMethodName != null) {
String[] patterns = StringUtils.commaDelimitedListToStringArray(destroyMethodName);
bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
}
} else {
bd.setAutowireCandidate("true".equals(autowireCandidate));
}
//解析primary属性
if (ele.hasAttribute("primary")) {
bd.setPrimary("true".equals(ele.getAttribute("primary")));
}
//解析init-method属性
if (ele.hasAttribute("init-method")) {
destroyMethodName = ele.getAttribute("init-method");
bd.setInitMethodName(destroyMethodName);
} else if (this.defaults.getInitMethod() != null) {
bd.setInitMethodName(this.defaults.getInitMethod());
bd.setEnforceInitMethod(false);
}
//解析destroy-method属性
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);
}
//解析factory-method属性
if (ele.hasAttribute("factory-method")) {
bd.setFactoryMethodName(ele.getAttribute("factory-method"));
}
//解析factory-bean属性
if (ele.hasAttribute("factory-bean")) {
bd.setFactoryBeanName(ele.getAttribute("factory-bean"));
}
//将属性封装到AbstractBeanDefinition中
return bd;
}
解析元数据
this.parseMetaElements(ele, bd);
![](https://i-blog.csdnimg.cn/blog_migrate/59f304c99739833db1b1cb1bf5be4bb9.png)
public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor) {
//获取所有的子节点
NodeList nl = ele.getChildNodes();
//循环遍历子节点
for(int i = 0; i < nl.getLength(); ++i) {
Node node = nl.item(i);
//提取matedata
if (this.isCandidateElement(node) && this.nodeNameEquals(node, "meta")) {
Element metaElement = (Element)node;
String key = metaElement.getAttribute("key");
String value = metaElement.getAttribute("value");
//以key value形式保存元数据至BeanMetadataAttribute中
BeanMetadataAttribute attribute = new BeanMetadataAttribute(key, value);
attribute.setSource(this.extractSource(metaElement));
attributeAccessor.addMetadataAttribute(attribute);
}
}
}
解析lookup-method
this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides())
![](https://i-blog.csdnimg.cn/blog_migrate/77cffccaf9509ffd30bf4054994e9e56.png)
<bean class="com.gongj.lookupMethod.Banana" id="banana"></bean>
<bean class="com.gongj.lookupMethod.TestLookupMethod" id="lookupMethod">
<lookup-method name="getBean" bean="banana"></lookup-method>
</bean>
public void parseLookupOverrideSubElements(Element beanEle, MethodOverrides overrides) {
//获取所有的子节点
NodeList nl = beanEle.getChildNodes();
//遍历
for(int i = 0; i < nl.getLength(); ++i) {
Node node = nl.item(i);
//如果是Spring默认的节点,并且是<lookup-method时生效
if (this.isCandidateElement(node) && this.nodeNameEquals(node, "lookup-method")) {
Element ele = (Element)node;
//需要修饰的方法名
String methodName = ele.getAttribute("name");
//替换后的bean
String beanRef = ele.getAttribute("bean");
// 根据 methodName、beanRef 构建 LookupOverride 对象
LookupOverride override = new LookupOverride(methodName, beanRef);
override.setSource(this.extractSource(ele));
//保存
overrides.addOverride(override);
}
}
}
解析replaced-method元素
this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides())
![](https://i-blog.csdnimg.cn/blog_migrate/0683bef0c5cca3368653f95ff6f5f2ed.png)
<bean class="com.gongj.lookupMethod.Replaced" id="replaced">
<replaced-method name="replacedName" replacer="replacedMethod">
<!--<arg-type></arg-type>可以配置任意多个 取决于想替换哪个重载方法-->
<arg-type>String</arg-type>
<arg-type>Integer</arg-type>
</replaced-method>
</bean>
<!-- replacedMethod -->
<bean class="com.gongj.lookupMethod.TestReplacedMethod" id="replacedMethod"></bean>
public void parseReplacedMethodSubElements(Element beanEle, MethodOverrides overrides) {
//获取所有的子节点
NodeList nl = beanEle.getChildNodes();
//遍历
for(int i = 0; i < nl.getLength(); ++i) {
Node node = nl.item(i);
//如果是Spring默认标签并且是<replaced-method开头时生效
if (this.isCandidateElement(node) && this.nodeNameEquals(node, "replaced-method")) {
Element replacedMethodEle = (Element)node;
//被替换的方法
String name = replacedMethodEle.getAttribute("name");
//替换后的方法
String callback = replacedMethodEle.getAttribute("replacer");
// 根据 name、replacer 构建 ReplaceOverride 对象
ReplaceOverride replaceOverride = new ReplaceOverride(name, callback);
//寻找arg-type元素
List<Element> argTypeEles = DomUtils.getChildElementsByTagName(replacedMethodEle, "arg-type");
Iterator var11 = argTypeEles.iterator();
while(var11.hasNext()) {
//记录参数
Element argTypeEle = (Element)var11.next();
String match = argTypeEle.getAttribute("match");
match = StringUtils.hasText(match) ? match : DomUtils.getTextValue(argTypeEle);
if (StringUtils.hasText(match)) {
replaceOverride.addTypeIdentifier(match);
}
}
replaceOverride.setSource(this.extractSource(replacedMethodEle));
// 将该对象添加到 MethodOverrides对象里的 overrides集合中
overrides.addOverride(replaceOverride);
}
}
}
解析子元素constructor-arg标签
this.parseConstructorArgElements(ele, bd)
![](https://i-blog.csdnimg.cn/blog_migrate/062fcd9a27689f462369945fbb492932.png)
public void parseConstructorArgElements(Element beanEle, BeanDefinition bd) {
//获取子节点
NodeList nl = beanEle.getChildNodes();
//遍历
for(int i = 0; i < nl.getLength(); ++i) {
Node node = nl.item(i);
//当是Spring默认标签并且以<constructor-arg开头时生效
if (this.isCandidateElement(node) && this.nodeNameEquals(node, "constructor-arg")) {
//解析
this.parseConstructorArgElement((Element)node, bd);
}
}
}
this.parseConstructorArgElement((Element)node, bd)
public void parseConstructorArgElement(Element ele, BeanDefinition bd) {
//获取index属性
String indexAttr = ele.getAttribute("index");
//获取type属性
String typeAttr = ele.getAttribute("type");
//获取name属性
String nameAttr = ele.getAttribute("name");
//当存在index标签时
if (StringUtils.hasLength(indexAttr)) {
try {
int index = Integer.parseInt(indexAttr);
if (index < 0) {
this.error("'index' cannot be lower than 0", ele);
} else {
try {
//保存一个ConstructorArgumentEntry实例对象
this.parseState.push(new ConstructorArgumentEntry(index));
//解析properties的值
Object value = this.parsePropertyValue(ele, bd, (String)null);
ValueHolder valueHolder = new ValueHolder(value);
if (StringUtils.hasLength(typeAttr)) {
valueHolder.setType(typeAttr);
}
if (StringUtils.hasLength(nameAttr)) {
valueHolder.setName(nameAttr);
}
//保存到ValueHolder
valueHolder.setSource(this.extractSource(ele));
//不允许重复指定参数
if (bd.getConstructorArgumentValues().hasIndexedArgumentValue(index)) {
this.error("Ambiguous constructor-arg entries for index " + index, ele);
} else {
保存至indexedArgumentValue
bd.getConstructorArgumentValues().addIndexedArgumentValue(index, valueHolder);
}
} finally {
this.parseState.pop();
}
}
} catch (NumberFormatException var19) {
this.error("Attribute 'index' of tag 'constructor-arg' must be an integer", ele);
}
//当不存在index
} else {
try {
//调用无参构造,忽略index自动寻找
this.parseState.push(new ConstructorArgumentEntry());
//解析properties的值
Object value = this.parsePropertyValue(ele, bd, (String)null);
ValueHolder valueHolder = new ValueHolder(value);
if (StringUtils.hasLength(typeAttr)) {
valueHolder.setType(typeAttr);
}
if (StringUtils.hasLength(nameAttr)) {
valueHolder.setName(nameAttr);
}
//保存到ValueHolder
valueHolder.setSource(this.extractSource(ele));
//保存至genericArgumentValue
bd.getConstructorArgumentValues().addGenericArgumentValue(valueHolder);
} finally {
this.parseState.pop();
}
}
}
解析properties属性
this.parsePropertyValue(ele, bd, (String)null)
public Object parsePropertyValue(Element ele, BeanDefinition bd, @Nullable String propertyName) {
String elementName = propertyName != null ? "<property> element for property '" + propertyName + "'" : "<constructor-arg> element";
NodeList nl = ele.getChildNodes();
Element subElement = null;
//遍历子节点
for(int i = 0; i < nl.getLength(); ++i) {
Node node = nl.item(i);
//跳过描述和元数据
if (node instanceof Element && !this.nodeNameEquals(node, "description") && !this.nodeNameEquals(node, "meta")) {
if (subElement != null) {
this.error(elementName + " must not contain more than one sub-element", ele);
} else {
subElement = (Element)node;
}
}
}
//获取ref
boolean hasRefAttribute = ele.hasAttribute("ref");
//获取value
boolean hasValueAttribute = ele.hasAttribute("value");
//1.不允许既存在ref又存在value
//2.不允许ref或者value含有子元素
if (hasRefAttribute && hasValueAttribute || (hasRefAttribute || hasValueAttribute) && subElement != null) {
this.error(elementName + " is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele);
}
//如果存在ref
if (hasRefAttribute) {
//获取ref标签
String refName = ele.getAttribute("ref");
if (!StringUtils.hasText(refName)) {
this.error(elementName + " contains empty 'ref' attribute", ele);
}
存入RuntimeBeanReference中
RuntimeBeanReference ref = new RuntimeBeanReference(refName);
ref.setSource(this.extractSource(ele));
return ref;
//如果存在value
} else if (hasValueAttribute) {
//存入TypedStringValue
TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute("value"));
valueHolder.setSource(this.extractSource(ele));
return valueHolder;
} else if (subElement != null) {
//如果存在子元素,则解析子元素
return this.parsePropertySubElement(subElement, bd);
} else {
//如果不存在ref和value 直接报错
this.error(elementName + " must specify a ref or value", ele);
return null;
}
}
constructor-arg标签示例:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="student" class="com.sgcc.bean.Student">
<constructor-arg index="0" name="name" value="小黑"/>
<constructor-arg index="1" name="age" value="18"/>
</bean>
</beans>
解析子元素
parsePropertySubElement
public Object parsePropertySubElement(Element ele, @Nullable BeanDefinition bd, @Nullable String defaultValueType) {
//自定义标签解析
if (!this.isDefaultNamespace((Node)ele)) {
return this.parseNestedCustomElement(ele, bd);
//如果是bean标签
} else if (this.nodeNameEquals(ele, "bean")) {
BeanDefinitionHolder nestedBd = this.parseBeanDefinitionElement(ele, bd);
if (nestedBd != null) {
nestedBd = this.decorateBeanDefinitionIfRequired(ele, nestedBd, bd);
}
return nestedBd;
//解析ref
} else if (this.nodeNameEquals(ele, "ref")) {
//获取bean属性
String refName = ele.getAttribute("bean");
boolean toParent = false;
//如果存在父引用
if (!StringUtils.hasLength(refName)) {
//获取父bean属性
refName = ele.getAttribute("parent");
toParent = true;
if (!StringUtils.hasLength(refName)) {
this.error("'bean' or 'parent' is required for <ref> element", ele);
return null;
}
}
if (!StringUtils.hasText(refName)) {
this.error("<ref> element contains empty target attribute", ele);
return null;
} else {
//保存RuntimeBeanReference
RuntimeBeanReference ref = new RuntimeBeanReference(refName, toParent);
ref.setSource(this.extractSource(ele));
return ref;
}
//解析idref标签
} else if (this.nodeNameEquals(ele, "idref")) {
return this.parseIdRefElement(ele);
//解析value
} else if (this.nodeNameEquals(ele, "value")) {
return this.parseValueElement(ele, defaultValueType);
//解析空值
} else if (this.nodeNameEquals(ele, "null")) {
TypedStringValue nullHolder = new TypedStringValue((String)null);
nullHolder.setSource(this.extractSource(ele));
return nullHolder;
//解析array
} else if (this.nodeNameEquals(ele, "array")) {
return this.parseArrayElement(ele, bd);
//解析list
} else if (this.nodeNameEquals(ele, "list")) {
return this.parseListElement(ele, bd);
//解析set
} else if (this.nodeNameEquals(ele, "set")) {
return this.parseSetElement(ele, bd);
//解析map
} else if (this.nodeNameEquals(ele, "map")) {
return this.parseMapElement(ele, bd);
//解析props
} else if (this.nodeNameEquals(ele, "props")) {
return this.parsePropsElement(ele);
} else {
this.error("Unknown property sub-element: [" + ele.getNodeName() + "]", ele);
return null;
}
}
解析properties元素
properties标签示例
<bean id="test" class="TestClass">
<property name="teatStr"><value>aaa</value>
</property>
</bean>
<bean id="test2" class="TestClass">
<property name="L">
<list>
<value>aaa</value>
<value>bbb</value>
</list>
</property>
</bean>
this.parsePropertyElements(ele, bd)
![](https://i-blog.csdnimg.cn/blog_migrate/fac38e8398b0a011be6f827d7e0fcf4c.png)
this.parsePropertyElement((Element)node, bd)
![](https://i-blog.csdnimg.cn/blog_migrate/d2a3af60cd66f9a6501f4fb6ce3b1f13.png)
public void parsePropertyElement(Element ele, BeanDefinition bd) {
//获取name属性
String propertyName = ele.getAttribute("name");
if (!StringUtils.hasLength(propertyName)) {
this.error("Tag 'property' must have a 'name' attribute", ele);
} else {
this.parseState.push(new PropertyEntry(propertyName));
try {
//不允许对同一属性多次配置
if (!bd.getPropertyValues().contains(propertyName)) {
//解析值
Object val = this.parsePropertyValue(ele, bd, propertyName);
PropertyValue pv = new PropertyValue(propertyName, val);
//解析元数据
this.parseMetaElements(ele, pv);
pv.setSource(this.extractSource(ele));
//保存PropertyValue中
bd.getPropertyValues().addPropertyValue(pv);
return;
}
this.error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
} finally {
this.parseState.pop();
}
}
}
解析qualifier元素
qualifier标签示例
<bean id="test2" class="TestClass">
<qualifier type="org.Springframework.beans.factory.annotation.Qualifier" value="gf"/></qualifier>
</bean>
this.parseQualifierElements(ele, bd)
![](https://i-blog.csdnimg.cn/blog_migrate/53ae92a3a8f96a6601aa3538d4358acc.png)
public void parseQualifierElement(Element ele, AbstractBeanDefinition bd) {
//获取type元素
String typeName = ele.getAttribute("type");
if (!StringUtils.hasLength(typeName)) {
this.error("Tag 'qualifier' must have a 'type' attribute", ele);
} else {
this.parseState.push(new QualifierEntry(typeName));
try {
//保存至AutowireCandidateQualifier
AutowireCandidateQualifier qualifier = new AutowireCandidateQualifier(typeName);
qualifier.setSource(this.extractSource(ele));
//获取value属性
String value = ele.getAttribute("value");
if (StringUtils.hasLength(value)) {
//存入AutowireCandidateQualifier
qualifier.setAttribute("value", value);
}
//获取子节点
NodeList nl = ele.getChildNodes();
//遍历
for(int i = 0; i < nl.getLength(); ++i) {
Node node = nl.item(i);
if (this.isCandidateElement(node) && this.nodeNameEquals(node, "attribute")) {
Element attributeEle = (Element)node;
//获取key属性
String attributeName = attributeEle.getAttribute("key");
//获取value属性
String attributeValue = attributeEle.getAttribute("value");
//必须存在key和value
if (!StringUtils.hasLength(attributeName) || !StringUtils.hasLength(attributeValue)) {
this.error("Qualifier 'attribute' tag must have a 'name' and 'value'", attributeEle);
return;
}
//通过attributeName和attributeValue构建BeanMetadataAttribute
BeanMetadataAttribute attribute = new BeanMetadataAttribute(attributeName, attributeValue);
attribute.setSource(this.extractSource(attributeEle));
//存入qualifier
qualifier.addMetadataAttribute(attribute);
}
}
bd.addQualifier(qualifier);
} finally {
this.parseState.pop();
}
}
}
至此我们已经完成了配置文件XML转换为GenericBeanDefinition,也就是说XML的所有配置都在GenericBeanDefinition找到对应的属性,但是更为详细的信息存储于AbstractBeanDefinition中,现在我们一起来看看AbstractBeanDefinition到底是何方神圣
AbstractBeanDefinition
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable {
public static final String SCOPE_DEFAULT = "";
public static final int AUTOWIRE_NO = 0;
public static final int AUTOWIRE_BY_NAME = 1;
public static final int AUTOWIRE_BY_TYPE = 2;
public static final int AUTOWIRE_CONSTRUCTOR = 3;
/** @deprecated */
@Deprecated
public static final int AUTOWIRE_AUTODETECT = 4;
public static final int DEPENDENCY_CHECK_NONE = 0;
public static final int DEPENDENCY_CHECK_OBJECTS = 1;
public static final int DEPENDENCY_CHECK_SIMPLE = 2;
public static final int DEPENDENCY_CHECK_ALL = 3;
public static final String INFER_METHOD = "(inferred)";
//bean的class对象或者类的全限定名 对应bean属性class
@Nullable
private volatile Object beanClass;
//bean的作用域 对应bean属性scope
@Nullable
private String scope;
//是否抽象标识 对应bean属性abstract
private boolean abstractFlag;
//是否为懒加载 对应bean属性lazy-init
@Nullable
private Boolean lazyInit;
//注入模式 对应bean属性autowire
private int autowireMode;
//依赖检查
private int dependencyCheck;
//这里只会存放<bean/>标签的depends-on属性或是@DependsOn注解的值,对应bean属性depends-on
@Nullable
private String[] dependsOn;
//当该属性设置为false时,这样容器在查找自动装配的对象时,
//将不考虑该bean,即他不会被考虑作为其他bean自动装配的候选者,但是该bean本身
//还是可以使用自动装配来注入其他bean的
//对应bean属性autowire-candidate
private boolean autowireCandidate;
//当自动装配出现多个bean候选者时,将作为首选者,对应bean属性primary
private boolean primary;
//用于记录Qualifier,对应子元素qualifier
private final Map<String, AutowireCandidateQualifier> qualifiers;
@Nullable
private Supplier<?> instanceSupplier;
//允许访问非公开的构造器和方法
private boolean nonPublicAccessAllowed;
//指定解析构造函数的模式,是宽松还是严格
private boolean lenientConstructorResolution;
//工程类名 对应属性bean-factory
@Nullable
private String factoryBeanName;
//工厂方法名 对应属性factory-method
@Nullable
private String factoryMethodName;
//记录构造函数对应属性,对应bean属性constructor-arg
@Nullable
private ConstructorArgumentValues constructorArgumentValues;
//普通属性集合
@Nullable
private MutablePropertyValues propertyValues;
//存储lookup-method replaced-method
private MethodOverrides methodOverrides;
//初始方法 对应bean属性init-method
@Nullable
private String initMethodName;
//销毁方法 对应bean属性destroy-method
@Nullable
private String destroyMethodName;
//是否强制执行init方法
private boolean enforceInitMethod;
//是否执行destroy方法
private boolean enforceDestroyMethod;
//是否是合成类(是不是应用自定义的,例如生成AOP代理时,会用到某些辅助类,
//这些辅助类不是应用自定义的,这个就是合成类)
private boolean synthetic;
//Bean的角色,为用户自定义Bean
private int role;
//bean信息描述
@Nullable
private String description;
//bean定义的资源
@Nullable
private Resource resource;
//省略
}
lenientConstructorResolution
![](https://i-blog.csdnimg.cn/blog_migrate/4eb7d46856a3abd6c9fbbd4a561febd1.png)
总的来说,AbstractBeanDefinition保存的属性包括:
Bean的描述信息(例如是否是抽象类、是否单例)
depends-on属性(String类型,不是Class类型)
自动装配的相关信息
init函数、destroy函数的名字(String类型)
工厂方法名、工厂类名(String类型,不是Class类型)
构造函数形参的值
被IOC容器覆盖的方法
Bean的属性以及对应的值(在初始化后会进行填充)
好了,到此为止,我们已经分析了Spring默认bean标签的整体解析过程,下一步就是Spring对于bean进行进一步的装饰
装饰Bean
![](https://i-blog.csdnimg.cn/blog_migrate/8d7d8eeabd474c42e29716d886cdf4d4.png)
decorateBeanDefinitionIfRequired
![](https://i-blog.csdnimg.cn/blog_migrate/73adafd431734ff9dc5f378631234943.png)
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {
BeanDefinitionHolder finalDefinition = originalDef;
//获取所有的自定义属性
NamedNodeMap attributes = ele.getAttributes();
//遍历自定义属性,装饰需要装饰的属性
for(int i = 0; i < attributes.getLength(); ++i) {
Node node = attributes.item(i);
finalDefinition = this.decorateIfRequired(node, finalDefinition, containingBd);
}
//获取所有的子节点
NodeList children = ele.getChildNodes();
//遍历所有的子节点,装饰需要装饰的子节点
for(int i = 0; i < children.getLength(); ++i) {
Node node = children.item(i);
if (node.getNodeType() == 1) {
finalDefinition = this.decorateIfRequired(node, finalDefinition, containingBd);
}
}
return finalDefinition;
}
decorateIfRequired
![](https://i-blog.csdnimg.cn/blog_migrate/0e7f8c355307ef1e33e8ddff36f926d7.png)
public BeanDefinitionHolder decorateIfRequired(Node node, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {
//获取自定义属性或者子节点的命名空间
String namespaceUri = this.getNamespaceURI(node);
//如果是Spring默认命名空间则不处理
if (namespaceUri != null && !this.isDefaultNamespace(namespaceUri)) {
//根据命名空间获取对应的处理器
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler != null) {
//对自定义属性进行装饰
BeanDefinitionHolder decorated = handler.decorate(node, originalDef, new ParserContext(this.readerContext, this, containingBd));
if (decorated != null) {
return decorated;
}
} else if (namespaceUri.startsWith("http://www.springframework.org/schema/")) {
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;
}
注册Bean
![](https://i-blog.csdnimg.cn/blog_migrate/ff72307712bff08e030b2b5015c22687.png)
registerBeanDefinition
![](https://i-blog.csdnimg.cn/blog_migrate/453bcda4cdbf495188a66cec86d154a2.png)
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
//获取beanName
String beanName = definitionHolder.getBeanName();
//根据beanName注册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];
//根据别名注册Bean
registry.registerAlias(beanName, alias);
}
}
}
根据BeanName注册
registerBeanDefinition
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");
//判断当前的bean属性是否是AbstractBeanDefinition类型
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
//注册前最后一次校验
//主要校验的是overrideMethod校验,判断methodOverride是否与
//factoryMethod并存,或者methodOverride对应的方法不存在
((AbstractBeanDefinition)beanDefinition).validate();
} catch (BeanDefinitionValidationException var8) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var8);
}
}
//根据beanName在容器查找实例
BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
//判断是否允许覆盖
if (!this.isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
//不清楚
if (existingDefinition.getRole() < beanDefinition.getRole()) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
}
} else if (!beanDefinition.equals(existingDefinition)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
}
} else if (this.logger.isTraceEnabled()) {
this.logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
}
//以beanName为key,beanDefinition为value放入map容器中
this.beanDefinitionMap.put(beanName, beanDefinition);
//容器中不存在该bean实例
} else {
//判断是否已经创建过
//已创建
if (this.hasBeanCreationStarted()) {
//考虑并发情况,保证线程安全
synchronized(this.beanDefinitionMap) {
//覆盖同名的beanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
//创建beanDefinitionNames+1的集合
List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
//将beanDefinitionNames存入updatedDefinitions中
updatedDefinitions.addAll(this.beanDefinitionNames);
//添加增量的bean
updatedDefinitions.add(beanName);
//更新所有的beanDefinitionNames
this.beanDefinitionNames = updatedDefinitions;
//从单例BeanName列表中移除该beanName,
//如果this.manualSingletonNames中contains该beanName,执行remove操作
this.removeManualSingletonName(beanName);
}
//未创建
} else {
//放入beanDefinitionMap中
this.beanDefinitionMap.put(beanName, beanDefinition);
//在beanDefinitionNames添加beanName
this.beanDefinitionNames.add(beanName);
this.removeManualSingletonName(beanName);
}
// 将注册期间冻结的beanName列表清除,一个volatile修饰的String数组,
//Spring内存优化操作
this.frozenBeanDefinitionNames = null;
}
//判断是否存在beanDefinition并且存在Ioc容器中
if (existingDefinition == null && !this.containsSingleton(beanName)) {
if (this.isConfigurationFrozen()) {
this.clearByTypeCache();
}
} else {
//清除缓存
this.resetBeanDefinition(beanName);
}
}
根据别名注册
registerAlias
public void registerAlias(String name, String alias) {
Assert.hasText(name, "'name' must not be empty");
Assert.hasText(alias, "'alias' must not be empty");
//考虑并发情况,保证线程安全
synchronized(this.aliasMap) {
//如果别名与beanName一样,则删除别名
if (alias.equals(name)) {
this.aliasMap.remove(alias);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Alias definition '" + alias + "' ignored since it points to same name");
}
} else {
//获取别名得到注册名称
String registeredName = (String)this.aliasMap.get(alias);
if (registeredName != null) {
if (registeredName.equals(name)) {
return;
}
//如果不允许覆盖,跑出异常
if (!this.allowAliasOverriding()) {
throw new IllegalStateException("Cannot define alias '" + alias + "' for name '" + name + "': It is already registered for name '" + registeredName + "'.");
}
if (this.logger.isDebugEnabled()) {
this.logger.debug("Overriding alias '" + alias + "' definition for registered name '" + registeredName + "' with new target name '" + name + "'");
}
}
//校验别名环
//不允许出现:A->B A->C->B这种情况
this.checkForAliasCircle(name, alias);
//放入map容器中
this.aliasMap.put(alias, name);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Alias definition '" + alias + "' registered for name '" + name + "'");
}
}
}
}
最后通知监听器,注册完成
至此我们分析了Spring是如何解析XML中的默认Bean标签,并获取对应的属性,再进行装饰和
注册,下面我们来总结一下
总结
解析标签
解析bean标签
解析元数据标签
解析lookup-method标签
解析constructor-arg标签
解析properties标签
解析qualifier
将删除解析的内容全部存入AbstractBeanDefinition对应的属性中
如果某些自定义标签或者子节点需要装饰,则进行装饰
注册bean
根据beanName进行注册
根据别名进行注册