本節主要針對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); } }