上文說到Document已經加載完畢,此時到了Spring註冊BeanDefinition的時候。下面就一塊兒來探究下Spring是怎麼把Xml文檔註冊成BeanDefinition的吧。
registerBeanDefinitions方法
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { //1. 建立BeanDefinitionDocumentReader BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); //2. 設置documentReader的環境 documentReader.setEnvironment(getEnvironment()); //3. 查詢以前註冊的BeanDefinition的個數 int countBefore = getRegistry().getBeanDefinitionCount(); //4. 開始註冊BeanDefinition,注意裏面建立了一個Reader上下文 documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); //5. 計算這次註冊的BeanDefinition的個數 return getRegistry().getBeanDefinitionCount() - countBefore; }
使用BeanUtils建立一個DefaultBeanDefinitionDocumentReader對象,用於解析成BeanDefinition對象
private Class<?> documentReaderClass = DefaultBeanDefinitionDocumentReader.class; //建立一個BeanDefinitionDocumentReader,此處使用的是DefaultBeanDefinitionDocumentReader protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() { //利用反射機制,調用DefaultBeanDefinitionDocumentReader的構造函數,而後建立一個實例返回 return BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiateClass(this.documentReaderClass)); }
建立一個XmlReaderContext設置了命名空間解析器爲DefaultNamespaceHandlerResolverjava
protected XmlReaderContext createReaderContext(Resource resource) { if (this.namespaceHandlerResolver == null) { this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver(); } return new XmlReaderContext(resource, this.problemReporter, this.eventListener, this.sourceExtractor, this, this.namespaceHandlerResolver); } protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() { return new DefaultNamespaceHandlerResolver(getResourceLoader().getClassLoader()); }
用來處理不一樣的命名空間的解析器,這些映射規則是配置在META-INF/spring.handlers文件中(見附圖)好比對於xmlns爲http://www.springframework.org/schema/c的命名空間的處理器爲org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandlernode
public static final String DEFAULT_HANDLER_MAPPINGS_LOCATION = "META-INF/spring.handlers"; public DefaultNamespaceHandlerResolver(ClassLoader classLoader) { //設置類加載器和handlerMapping文件的位置 this(classLoader, DEFAULT_HANDLER_MAPPINGS_LOCATION); } public DefaultNamespaceHandlerResolver(ClassLoader classLoader, String handlerMappingsLocation) { Assert.notNull(handlerMappingsLocation, "Handler mappings location must not be null"); this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader()); this.handlerMappingsLocation = handlerMappingsLocation; }
註冊beanDefinition
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; logger.debug("Loading bean definitions"); //獲取xml的根元素<beans> Element root = doc.getDocumentElement(); //註冊BeanDefinition doRegisterBeanDefinitions(root); } protected void doRegisterBeanDefinitions(Element root) { //獲取 profile 屬性值,我此處並無設置此屬性值,因此使用的是默認的 String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE); //若是有配置profile,則進入 if (StringUtils.hasText(profileSpec)) { //將profile放入一個數組中 //profile能夠配置多個,中間以MULTI_VALUE_ATTRIBUTE_DELIMITERS(,或;)分隔 String[] specifiedProfiles = StringUtils.tokenizeToStringArray( profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); //判斷環境是否接受此profile數組,若是環境中不容許就直接返回,再也不進行註冊 //這就是爲何pfofile起做用的緣由,和環境中的prfile不一致的配置,不會被Spring註冊到容器中 if (!getEnvironment().acceptsProfiles(specifiedProfiles)) { return; } } // Any nested <beans> elements will cause recursion in this method. In // order to propagate and preserve <beans> default-* attributes correctly, // keep track of the current (parent) delegate, which may be null. Create // the new (child) delegate with a reference to the parent for fallback purposes, // then ultimately reset this.delegate back to its original (parent) reference. // this behavior emulates a stack of delegates without actually necessitating one. //任何嵌套的<beans>元素都將致使此方法中的遞歸。在爲了正確地傳播和保存<beans>缺省-*屬性,跟蹤當前(父)委託,它可能爲空。建立新的(子)委託,該委託具備對父委託的引用,用於備份,而後最終將this.delegate重置回其原始(父)引用。這種行爲模擬了一堆委託,實際上並不須要委託。這是直接翻譯的,可能比較書面語。 //口語化的描述是,由於在遞歸解析<beans>中,爲了正確的保持BeanDefinitionParserDelegate的引用關係,因此首先取出DefaultBeanDefinitionDocumentReader委託類暫存起來,而後建立一個新的委託類使用,最後再還原爲以前的委託類。 //獲取此DefaultBeanDefinitionDocumentReader的解析委託類 BeanDefinitionParserDelegate parent = this.delegate; //利用現有的委託類(可能爲null),建立一個新的委託類 this.delegate = createDelegate(this.readerContext, root, parent); //預處理root,當前是空實現,可自行擴展 preProcessXml(root); //真正的處理root,並註冊,詳細的見下一小節《parseBeanDefinitions》 parseBeanDefinitions(root, this.delegate); //後處理root,當前是空實現,可自行擴展 postProcessXml(root); this.delegate = parent; } //輔助方法分析 //建立一個新的委託類BeanDefinitionParserDelegate // protected BeanDefinitionParserDelegate createDelegate(XmlReaderContext readerContext, Element root, BeanDefinitionParserDelegate parentDelegate) { //目前createHelper返回的值都是null BeanDefinitionParserDelegate delegate = createHelper(readerContext, root, parentDelegate); //目前都會進入此判斷內 if (delegate == null) { //建立一個新的BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext, getEnvironment()); //初始化,並經過readerContext分發一個開始註冊BeanDefinition的事件 delegate.initDefaults(root, parentDelegate); } return delegate; } //BeanDefinitionParserDelegate.initDefaults //默認的文檔BeanDefinition private final DocumentDefaultsDefinition defaults = new DocumentDefaultsDefinition(); public void initDefaults(Element root, BeanDefinitionParserDelegate parent) { //給defaults設置初始值 populateDefaults(this.defaults, (parent != null ? parent.defaults : null), root); //分發一個defaultsRegistered事件 this.readerContext.fireDefaultsRegistered(this.defaults); } //讀取<beans>中配置的屬性,並設置到defaults中 protected void populateDefaults(DocumentDefaultsDefinition defaults, DocumentDefaultsDefinition parentDefaults, Element root) { //設置 default-lazy-init , //值爲default時,若是父節點不是null時,繼承父節的屬性值,不然爲false String lazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE); if (DEFAULT_VALUE.equals(lazyInit)) { lazyInit = parentDefaults != null ? parentDefaults.getLazyInit() : FALSE_VALUE; } defaults.setLazyInit(lazyInit); //設置 default-merge //值爲default時,若是父節點不是null時,繼承父節的屬性值,不然爲false String merge = root.getAttribute(DEFAULT_MERGE_ATTRIBUTE); if (DEFAULT_VALUE.equals(merge)) { merge = parentDefaults != null ? parentDefaults.getMerge() : FALSE_VALUE; } defaults.setMerge(merge); //設置 default-autowire //值爲default時,若是父節點不是null時,繼承父節的屬性值,不然爲no String autowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE); if (DEFAULT_VALUE.equals(autowire)) { autowire = parentDefaults != null ? parentDefaults.getAutowire() : AUTOWIRE_NO_VALUE; } defaults.setAutowire(autowire); // don't fall back to parentDefaults for dependency-check as it's no // longer supported in <beans> as of 3.0. Therefore, no nested <beans> // would ever need to fall back to it. //設置 default-dependency-check ,不用檢查父節點的值了 defaults.setDependencyCheck(root.getAttribute(DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE)); //設置 default-autowire-candidates if (root.hasAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE)) { defaults.setAutowireCandidates(root.getAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE)); } else if (parentDefaults != null) { defaults.setAutowireCandidates(parentDefaults.getAutowireCandidates()); } //設置 default-init-method if (root.hasAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE)) { defaults.setInitMethod(root.getAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE)); } else if (parentDefaults != null) { defaults.setInitMethod(parentDefaults.getInitMethod()); } //設置 default-destroy-method if (root.hasAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE)) { defaults.setDestroyMethod(root.getAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE)); } else if (parentDefaults != null) { defaults.setDestroyMethod(parentDefaults.getDestroyMethod()); } //設置此DocumentDefaultsDefinition的元數據源 defaults.setSource(this.readerContext.extractSource(root)); }
一個beans的圖示spring
委託模式石錘了!這裏把root交給委託類delegate來處理,委託類delegate經過XmlReaderContext持有當前的XmlBeanDefinitionReader、命名空間解析器、原始資源、事件分發器等,又直接持有環境的引用,而XmlBeanDefinitionReader又有BeanDefinitionRegistry的引用,能夠說集萬千寵愛於一身,因此能力很是強大。我不得不畫個圖來表示一下敬意!數組
這裏解析是的app
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { //判斷root的xlmns是否是默認的名稱空間,即"http://www.springframework.org/schema/beans" //這裏是的 if (delegate.isDefaultNamespace(root)) { //獲取所有子節點並遍歷 NodeList nl = root.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); //若是節點是Element的話,這裏主要是爲了去除xml中無用的Text空節點 //好比:__<A>a</A>__<B></B>__ 是有5個Node的 //分別是: //1. 空白Text節點 //2. <A>節點 //3. 空白Text節點 //4. <B>節點 //5. 空白Text節點 if (node instanceof Element) { Element ele = (Element) node; if (delegate.isDefaultNamespace(ele)) { //解析有效節點,處理不一樣的標籤 import bean alias beans parseDefaultElement(ele, delegate); } else { delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } }
處理import 、alias、bean、beans 這四種標籤其中最複雜的就是 beans 標籤,他會致使程序遞歸到DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions方法,而後重複上面的全部步驟,有興趣的同窗能夠在< beans> 標籤中嵌入一個< beans>,來研究下Spring是如何處理遞歸的。我這裏就再也不深刻討論了。ide
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { //處理 import 標籤 if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } // //處理 alias 標籤 else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); } //處理 bean 標籤 else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { processBeanDefinition(ele, delegate); } //處理 beans 標籤 else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // recurse doRegisterBeanDefinitions(ele); } }
處理bean標籤,先解析默認命名空間中的屬性、和子標籤而後處理非默認命名空間的標籤函數
接着註冊BeanDefinitionpost
最後發送一個BeanDefinition註冊事件ui
/** * Process the given bean element, parsing the bean definition * and registering it with the registry. */ protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { //解析ele成BeanDefinition,並放入到BeanDefinitionHolder中 BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); //若是bdHolder解析成功了就進行 if (bdHolder != null) { //解析非默認命名空間的屬性 //好比 http://www.springframework.org/schema/c 之類的標籤 //對應的解析器也是就在springs.handlers文件中配置的,好比*/c的是org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { //向IOC中註冊該BeanDefiniton!!! BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex); } //最後發送一個BeanDefinition註冊事件 getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } }
//調用parseBeanDefinitionElement public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) { return parseBeanDefinitionElement(ele, null); } //實際將Element解析成Beanfinition的方法 public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) { //獲取id屬性 String id = ele.getAttribute(ID_ATTRIBUTE); //獲取name屬性 String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); //別名list List<String> aliases = new ArrayList<String>(); //若是name屬性值不爲空,按照 ,; 符號切分name,切分紅一個name屬性,並放入到aliases中 //這裏看出bean的定義,能夠定義多個name值,只要經過逗號或者分號分隔便可。 if (StringUtils.hasLength(nameAttr)) { String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS); aliases.addAll(Arrays.asList(nameArr)); } //把beanName設置成id, String beanName = id; //若是沒有配置id,就把name中配置的第一個值做爲beanName if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) { beanName = aliases.remove(0); if (logger.isDebugEnabled()) { logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases"); } } //若是傳入的containingBean爲null,就檢驗beanName和aliases是否是已經被佔用了, //佔用了就拋出一個異常BeanDefinitionParsingException, //這裏傳入的containingBean就是null,因此必定要通過裏面檢查 if (containingBean == null) { checkNameUniqueness(beanName, aliases, ele); } //把ele解析 beanDefinition, //其中此處的 beanDefinition的類型是GenericBeanDefinition AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); if (beanDefinition != null) { //若是beanName沒有的話,就使用BeanDefinitionReaderUtils.generateBeanName生成一個名字 if (!StringUtils.hasText(beanName)) { try { if (containingBean != null) { beanName = BeanDefinitionReaderUtils.generateBeanName( beanDefinition, this.readerContext.getRegistry(), true); } else { beanName = this.readerContext.generateBeanName(beanDefinition); // Register an alias for the plain bean class name, if still possible, // if the generator returned the class name plus a suffix. // This is expected for Spring 1.2/2.0 backwards compatibility. String beanClassName = beanDefinition.getBeanClassName(); if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) { aliases.add(beanClassName); } } if (logger.isDebugEnabled()) { logger.debug("Neither XML 'id' nor 'name' specified - " + "using generated bean name [" + beanName + "]"); } } catch (Exception ex) { error(ex.getMessage(), ele); return null; } } String[] aliasesArray = StringUtils.toStringArray(aliases); // 用一個BeanDefinitionHolder ,把beanDefinition, beanName, aliasesArray封裝在一塊兒而後返回 return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); } return null; }
//檢查benaName、aliases是否被以前的bean佔用 protected void checkNameUniqueness(String beanName, List<String> aliases, Element beanElement) { String foundName = null; //判斷beanName是否被使用 if (StringUtils.hasText(beanName) && this.usedNames.contains(beanName)) { foundName = beanName; } //判斷是否aliases中有被佔用的 if (foundName == null) { foundName = (String) CollectionUtils.findFirstMatch(this.usedNames, aliases); } //若是找到了佔用,就拋出異常 if (foundName != null) { error("Bean name '" + foundName + "' is already used in this <beans> element", beanElement); } //若是沒有發現佔用,就把beanName和aliaes所有放入到usedNames中 this.usedNames.add(beanName); this.usedNames.addAll(aliases); }
解析Bean中幾乎全部的屬性和一些配置的子標籤,一個示例Bean標籤的配置如圖
//Element解析成AbstractBeanDefinition public AbstractBeanDefinition parseBeanDefinitionElement( Element ele, String beanName, BeanDefinition containingBean) { //把beanName壓入到棧parseState中 this.parseState.push(new BeanEntry(beanName)); String className = null; //獲取class屬性值,放入到className中 if (ele.hasAttribute(CLASS_ATTRIBUTE)) { className = ele.getAttribute(CLASS_ATTRIBUTE).trim(); } try { //若是有parent屬性,設置到parent中 String parent = null; if (ele.hasAttribute(PARENT_ATTRIBUTE)) { parent = ele.getAttribute(PARENT_ATTRIBUTE); } //建立一個AbstractBeanDefinition,類型是GenericBeanDefinition AbstractBeanDefinition bd = createBeanDefinition(className, parent); //解析ele的屬性,並設置到BeanDefinition中 parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); //若是此bean標籤有子標籤description的話,就把description中的值設置到bd中 // <description>message</description> bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT)); //解析<meta>子標籤 // <meta key="bk" value="bv"/> parseMetaElements(ele, bd); //解析<lookup-method> 子標籤,把配置的lookup-method放入到bd的methodOverrides中 // <lookup-method name="getAdmin" bean="parent"/> parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); //解析 replaced-method 標籤 // <replaced-method name="toString" replacer="methodPlacer"/> parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); //解析 構造函數標籤 <constructor-arg> // <constructor-arg name="name" value="nn"/> parseConstructorArgElements(ele, bd); //解析 屬性標籤 <property> parsePropertyElements(ele, bd); //解析 <qualifier> 標籤 parseQualifierElements(ele, bd); bd.setResource(this.readerContext.getResource()); bd.setSource(extractSource(ele)); return bd; } catch (ClassNotFoundException ex) { error("Bean class [" + className + "] not found", ele, ex); } catch (NoClassDefFoundError err) { error("Class that bean class [" + className + "] depends on not found", ele, err); } catch (Throwable ex) { error("Unexpected failure during bean definition parsing", ele, ex); } finally { this.parseState.pop(); } return null; }
//利用className和parentName建立一個BeanDefinition protected AbstractBeanDefinition createBeanDefinition(String className, String parentName) throws ClassNotFoundException { return BeanDefinitionReaderUtils.createBeanDefinition( parentName, className, this.readerContext.getBeanClassLoader()); } //BeanDefinitionReaderUtils.createBeanDefinition方法建立的BeanDefinition的類型是GenericBeanDefinition public static AbstractBeanDefinition createBeanDefinition( String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException { //建立一個GenericBeanDefinition,設置ParentName, GenericBeanDefinition bd = new GenericBeanDefinition(); bd.setParentName(parentName); //若是能夠className和classLoader都有值的話,就把類Class加載出來,並設置到bd中 //若是classLoder爲空的話,就只設置一個className if (className != null) { if (classLoader != null) { // bd.setBeanClass(ClassUtils.forName(className, classLoader)); } else { bd.setBeanClassName(className); } } return bd; }
幾乎設置了一個BeanDefinition須要的所有屬性
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, BeanDefinition containingBean, AbstractBeanDefinition bd) { //解析spring2.x中的scope屬性 //解析Spring1.x中的singleton屬性 if (ele.hasAttribute(SCOPE_ATTRIBUTE)) { // Spring 2.x "scope" attribute bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE)); if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) { error("Specify either 'scope' or 'singleton', not both", ele); } } else if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) { // Spring 1.x "singleton" attribute bd.setScope(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)) ? BeanDefinition.SCOPE_SINGLETON : BeanDefinition.SCOPE_PROTOTYPE); } else if (containingBean != null) { // Take default from containing bean in case of an inner bean definition. bd.setScope(containingBean.getScope()); } //設置bd的 abstract 屬性 if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) { bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE))); } //設置bd的 lazy-init 屬性 String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE); if (DEFAULT_VALUE.equals(lazyInit)) { lazyInit = this.defaults.getLazyInit(); } bd.setLazyInit(TRUE_VALUE.equals(lazyInit)); //設置bd的 autowire 屬性 String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE); bd.setAutowireMode(getAutowireMode(autowire)); //設置bd的 dependency-check 屬性 String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE); bd.setDependencyCheck(getDependencyCheck(dependencyCheck)); //設置bd的 depends-on 屬性 if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) { String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE); bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS)); } //設置bd的 autowire-candidate 屬性 String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE); if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) { String candidatePattern = this.defaults.getAutowireCandidates(); if (candidatePattern != null) { String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern); bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName)); } } else { bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate)); } //設置bd的 primary 屬性 if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) { bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE))); } //設置bd的 init-method 屬性 if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) { String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE); if (!"".equals(initMethodName)) { bd.setInitMethodName(initMethodName); } } else { if (this.defaults.getInitMethod() != null) { bd.setInitMethodName(this.defaults.getInitMethod()); bd.setEnforceInitMethod(false); } } //設置bd的 destroy-method 屬性 if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) { String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE); if (!"".equals(destroyMethodName)) { bd.setDestroyMethodName(destroyMethodName); } } else { if (this.defaults.getDestroyMethod() != null) { bd.setDestroyMethodName(this.defaults.getDestroyMethod()); bd.setEnforceDestroyMethod(false); } } //設置bd的 factory-method 屬性 if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) { bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE)); } //設置bd的 factory-bean 屬性 if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) { bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE)); } return bd; }
BeanDefinition的繼承關係圖,能夠看出GenericBeanDefinition的位置this
寫的有點太多了,還有import標籤和 alias標籤的解析內容,我放置《BeanDefinition註冊-下篇》中一塊兒講解。下篇中也會補充一些此文中關於註冊BeanDefintion的細節內容。