本节主要针对bean标签的解析源码分析
DefaultBeanDefinitionDocumentReader.java 完成了对element的解析
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对象
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以及别名信息是否唯一
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信息。
【分支0102】创建一个beanDefinition对象(其原型类为AbstractBeanDefinition)
BeanDefinitionParserDelegate.java中
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配置中对属性节点的解析。
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);
}
}