BeanDefinitionParserDelegate用来解析spring的配置文件的
默认命名空间中
以bean开头的配置,由parseBeanDefinitionElement方法解析。
bean的id和name属性的作用差不多,name属于别名性质的,都是唯一不能重复的。
下面返回的BeanDefinitionHolder持有一个GenericBeanDefinition的成员变量,以及这个bean的name和别名。
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
String id = ele.getAttribute("id");
String nameAttr = ele.getAttribute("name");
List<String> aliases = new ArrayList();
if(StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; ");
aliases.addAll(Arrays.asList(nameArr));
}
String beanName = id;
if(!StringUtils.hasText(id) && !aliases.isEmpty()) {
beanName = (String)aliases.remove(0);
if(this.logger.isDebugEnabled()) {
this.logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases");
}
}
if(containingBean == null) {//检查id和name有没有与其他对象的重复
this.checkNameUniqueness(beanName, aliases, ele);//usedNames中检查,这是一个hashset
}
AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName, containingBean);
if(beanDefinition != null) {
if(!StringUtils.hasText(beanName)) {
try {
if(containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);
} else {
beanName = this.readerContext.generateBeanName(beanDefinition);
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.isDebugEnabled()) {
this.logger.debug("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);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
} else {
return null;
}
}
解析这个bean节点的属性
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));//压栈
String className = null;
if(ele.hasAttribute("class")) {
className = ele.getAttribute("class").trim();
}
try {
String parent = null;
if(ele.hasAttribute("parent")) {//一般是没设置的
parent = ele.getAttribute("parent");
}
AbstractBeanDefinition bd = this.createBeanDefinition(className, parent);
//创建GenericBeanDefinition对象,设置beanName,加载beanClass
this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, "description"));//忽略
this.parseMetaElements(ele, bd);//解析这个bean有没有meta子节点,有的话配置属性
this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides());//查找lookup-method,覆盖
//replaced-method子节点,替换。name,replacer
// <replaced-method name="close" replacer="c">
// <arg-type match=""></arg-type>
// </replaced-method>
this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
//设置构造函数参数constructor-arg,index,type,name/还有 ref或者value
this.parseConstructorArgElements(ele, bd);
//解析property节点,属性name,ref或者value
this.parsePropertyElements(ele, bd);
//解析qualifier节点,属性有type,value。可以有子节点attribute,子节点属性key,value
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;
}
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, BeanDefinition containingBean, AbstractBeanDefinition bd) {
//设置scope属性
if(ele.hasAttribute("singleton")) {
this.error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
} else if(ele.hasAttribute("scope")) {
bd.setScope(ele.getAttribute("scope"));
} else if(containingBean != null) {
bd.setScope(containingBean.getScope());
}
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));
//autowire的属性有byName,byType,constructor,autodetect
String autowire = ele.getAttribute("autowire");
bd.setAutowireMode(this.getAutowireMode(autowire));
//dependency-check的属性all,objects,simple
String dependencyCheck = ele.getAttribute("dependency-check");
bd.setDependencyCheck(this.getDependencyCheck(dependencyCheck));
//depends-on属性
String autowireCandidate;
if(ele.hasAttribute("depends-on")) {
autowireCandidate = ele.getAttribute("depends-on");
bd.setDependsOn(StringUtils.tokenizeToStringArray(autowireCandidate, ",; "));
}
//AutowireCandidate是true或者false,不填true的是false
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")));
}
//设置初始化方法init-method
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;
}
非默认命名空间的节点
有parseCustomElement方法解析,先根据该Node的命名空间找到META-INF/spring.handlers中定义的解析器,然后由相应的解析器解析节点。
全部内容如下:
http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
http\://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler
http\://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler
http\://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler
http\://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler
http\://www.springframework.org/schema/c=org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler
http\://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler
http\://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler
http\://www.springframework.org/schema/mvc=org.springframework.web.servlet.config.MvcNamespaceHandler
http\://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
String namespaceUri = this.getNamespaceURI(ele);
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if(handler == null) {
this.error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
} else {
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
}
比较常见的是context和aop这两个命名空间的解析,下面分析一下这两个。